entity framework5 MaxLength

我使用EF4和我发现的一段代码从这样的实体获取MaxLength值:

 public static int? GetMaxLength(string entityTypeName, string columnName) { int? result = null; using (fooEntities context = new fooEntities()) { Type entType = Type.GetType(entityTypeName); var q = from meta in context.MetadataWorkspace.GetItems(DataSpace.CSpace) .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType) from p in (meta as EntityType).Properties .Where(p => p.Name == columnName && p.TypeUsage.EdmType.Name == "String") select p; var queryResult = q.Where(p => { bool match = p.DeclaringType.Name == entityTypeName; if (!match && entType != null) { match = entType.Name == p.DeclaringType.Name; } return match; }).Select(sel => sel.TypeUsage.Facets["MaxLength"].Value); if (queryResult.Any()) { result = Convert.ToInt32(queryResult.First()); } return result; } } 

但是,我升级到EF5,我知道收到此错误消息:

 ...fooEntities' does not contain a definition for 'MetadataWorkspace' and no extension method 'MetadataWorkspace' accepting a first argument of type '...fooEntities' could be found (are you missing a using directive or an assembly reference?) 

从EF5获取元数据的最佳方法是什么?

这意味着您不仅升级了EF,而且还更改了API。 有两个API – 核心ObjectContext API和简化的DbContext API。 您的代码依赖于ObjectContext API(EF4中唯一可用的API),但EF5使用DbContext API(自EF4.1起添加在单独的EntityFramework.dll程序集中)。 如果您想使用新的EFfunction和以前的代码,您应该只升级到.NET 4.5。

如果您还想使用新的API,则必须更新大量现有代码,但仍然可以从DbContext获取ObjectContext并使您的方法再次运行。 您只需要使用此代码段:

 var objectContext = ((IObjectContextAdapter)context).ObjectContext; 

并在代码中使用objectContext而不是context

这是一个非常方便的代码。 我稍微重构了它,它非常有用,我想我会在这里发布它。

 public static int? GetMaxLength(Expression> column) { int? result = null; using (var context = new EfContext()) { var entType = typeof(T); var columnName = ((MemberExpression) column.Body).Member.Name; var objectContext = ((IObjectContextAdapter) context).ObjectContext; var test = objectContext.MetadataWorkspace.GetItems(DataSpace.CSpace); if(test == null) return null; var q = test .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType) .SelectMany(meta => ((EntityType) meta).Properties .Where(p => p.Name == columnName && p.TypeUsage.EdmType.Name == "String")); var queryResult = q.Where(p => { var match = p.DeclaringType.Name == entType.Name; if (!match) match = entType.Name == p.DeclaringType.Name; return match; }) .Select(sel => sel.TypeUsage.Facets["MaxLength"].Value) .ToList(); if (queryResult.Any()) result = Convert.ToInt32(queryResult.First()); return result; } } 

你可以称之为:

 GetMaxLength(x => x.CustomerName); 

这假设您在DbContext中定义了一个类型为Customer的DbSet,它具有CustomerName属性,并具有已定义的MaxLength。

这对于创建模型属性非常有用,这些属性将文本框的maxlength设置为数据库中字段的最大长度,始终确保两者相同。

我将mccow002的示例重构为一个准备好复制粘贴的Extension方法类:

 using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Metadata.Edm; public static class DbContextExtensions { // get MaxLength as an extension method to the DbContext public static int? GetMaxLength(this DbContext context, Expression> column) { return (int?)context.GetFacets(column)["MaxLength"].Value; } // get MaxLength as an extension method to the Facets (I think the extension belongs here) public static int? GetMaxLength(this ReadOnlyMetadataCollection facets) { return (int?)facets["MaxLength"].Value; } // just for fun: get all the facet values as a Dictionary public static Dictionary AsDictionary(this ReadOnlyMetadataCollection facets) { return facets.ToDictionary(o=>o.Name,o=>o.Value); } public static ReadOnlyMetadataCollection GetFacets(this DbContext context, Expression> column) { ReadOnlyMetadataCollection result = null; var entType = typeof(T); var columnName = ((MemberExpression)column.Body).Member.Name; var objectContext = ((IObjectContextAdapter)context).ObjectContext; var test = objectContext.MetadataWorkspace.GetItems(DataSpace.CSpace); if (test == null) return null; var q = test .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType) .SelectMany(meta => ((EntityType)meta).Properties .Where(p => p.Name == columnName && p.TypeUsage.EdmType.Name == "String")); var queryResult = q.Where(p => { var match = p.DeclaringType.Name == entType.Name; if (!match) match = entType.Name == p.DeclaringType.Name; return match; }) .Select(sel => sel) .FirstOrDefault(); result = queryResult.TypeUsage.Facets; return result; } } 

我有类似的问题和解决方案在这里;

  MyDBEntities ctx = new MyDBEntities(); var objectContext = ((IObjectContextAdapter)ctx).ObjectContext; var cols = from meta in objectContext.MetadataWorkspace.GetItems(DataSpace.CSpace) .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType) from p in (meta as EntityType).Properties .Where(p => p.DeclaringType.Name == "TableName") select new { PropertyName = p.Name };