Mineplex2018-withcommit/Website/LOC.Core/Data/ContextExtensions.cs

184 lines
7.1 KiB
C#

namespace LOC.Core.Data
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Metadata.Edm;
using System.Data.Objects;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
public static class ContextExtensions
{
private const string INDITIFY_OBJECT = "SELECT * FROM sys.indexes where name='{0}'";
public static object[] KeyValuesFor<TEntity>(this DbContext context, TEntity entity) where TEntity : class
{
var entry = context.Entry(entity);
return context.KeysFor(entity.GetType()).Select(x => entry.Property(x).CurrentValue).ToArray();
}
public static IQueryable<TEntity> LoadNavigationProperties<TEntity>(this IQueryable<TEntity> query, DbContext context)
where TEntity : class
{
var entityType = GetEntityType(context, typeof(TEntity));
if (entityType == null)
{
throw new ArgumentException(string.Format("The type '{0}' is not mapped as an entity type.", entityType.Name));
}
return entityType.NavigationProperties.Aggregate(
query,
(current, navigationProperty) => current.Include(navigationProperty.Name));
}
public static void LoadNavigationProperties<TEntity>(this TEntity entity, DbContext context) where TEntity : class
{
if (entity == null)
{
return;
}
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var items = objectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.OSpace);
var item = items == null
? null
: items.FirstOrDefault(x => x.Name.Equals(ObjectContext.GetObjectType(entity.GetType()).Name));
var navigationPropertyNames = item == null ? new List<string>() : item.NavigationProperties.Select(x => x.Name);
foreach (var prop in navigationPropertyNames)
{
objectContext.LoadProperty(entity, prop);
}
}
public static void CreateIndex<T>(this DbContext context, Expression<Func<T, object>> expression, bool isUnique) where T : class
{
var database = context.Database;
if (database == null)
{
throw new ArgumentNullException("context", @"Database is null");
}
var realtableName = GetTableName<T>(context);
var tablename = typeof(T).Name;
var columnName = GetColumnExpressionName(expression.Body);
var indexColumnName = GetColumnName(expression.Body);
var indexName = string.Format("IX_{0}_{1}", tablename, columnName);
var createIndexSql = string.Format(
isUnique ? "CREATE UNIQUE INDEX {0} ON {1} ({2})" : "CREATE INDEX {0} ON {1} ({2})",
indexName,
realtableName,
indexColumnName);
//TODO Check index?
var checkIndex = string.Format(INDITIFY_OBJECT, indexName);
var result = database.SqlQuery<object>(checkIndex).Count();
if (result <= 0)
{
//TODO Create index
database.ExecuteSqlCommand(createIndexSql);
}
}
private static string GetColumnExpressionName(Expression expression)
{
var memberExps = expression as NewExpression;
if (memberExps != null)
{
var sb = new StringBuilder();
foreach (var memberExp in memberExps.Arguments)
{
var member = memberExp as MemberExpression;
if (memberExp == null
|| member == null)
{
throw new ArgumentException(@"Cannot get name from expression", "expression");
}
sb.Append(member.Member.Name);
sb.Append("_");
}
return sb.ToString().Substring(0, sb.ToString().Length - 1);
}
return string.Empty;
}
private static string GetColumnName(Expression expression)
{
var memberExps = expression as NewExpression;
if (memberExps != null)
{
var sb = new StringBuilder();
foreach (var memberExp in memberExps.Arguments)
{
var member = memberExp as MemberExpression;
if (memberExp == null
|| member == null)
{
throw new ArgumentException(@"Cannot get name from expression", "expression");
}
sb.Append(member.Member.Name);
sb.Append(",");
}
return sb.ToString().Substring(0, sb.ToString().Length - 1);
}
return string.Empty;
}
private static EntityType GetEntityType(IObjectContextAdapter context, Type entityType)
{
entityType = ObjectContext.GetObjectType(entityType);
var workspace = context.ObjectContext.MetadataWorkspace;
var itemCollection = (ObjectItemCollection)workspace.GetItemCollection(DataSpace.OSpace);
EntityType type;
if (workspace == null)
{
type = null;
}
else
{
var types = workspace.GetItems<EntityType>(DataSpace.OSpace);
type = types == null ? null : types.SingleOrDefault(t => itemCollection.GetClrType(t) == entityType);
}
return type;
}
private static string GetTableName<T>(IObjectContextAdapter context) where T : class
{
var objectContext = context.ObjectContext;
return GetTableName<T>(objectContext);
}
private static string GetTableName<T>(ObjectContext context) where T : class
{
var sql = context.CreateObjectSet<T>().ToTraceString();
var regex = new Regex("FROM (?<table>.*) AS");
var match = regex.Match(sql);
var table = match.Groups["table"].Value;
return table;
}
private static IEnumerable<string> KeysFor(this IObjectContextAdapter context, Type entityType)
{
var type = GetEntityType(context, entityType);
if (type == null)
{
throw new ArgumentException(
string.Format("The type '{0}' is not mapped as an entity type.", entityType.Name), "entityType");
}
return type.KeyMembers.Select(k => k.Name);
}
}
}