structure d’entité 5 MaxLength

J’utilisais EF4 et un morceau de code que j’ai trouvé pour obtenir la valeur MaxLength d’une entité comme celle-ci:

 public static int? GetMaxLength(ssortingng entityTypeName, ssortingng 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 == "Ssortingng") 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; } } 

Cependant, je suis passé à EF5 et je sais obtenir ce message d’erreur:

 ...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?) 

Quel est le meilleur moyen d’obtenir ces métadonnées à partir de EF5?

Cela signifie que vous avez non seulement mis à niveau EF, mais également modifié l’API. Il existe deux API: l’API ObjectContext principale et l’API DbContext simplifiée. Votre code dépend de l’API ObjectContext (la seule API disponible dans EF4), mais EF5 utilise l’API DbContext (ajouté dans l’assembly EntityFramework.dll séparé depuis EF4.1). Si vous souhaitez utiliser les nouvelles fonctionnalités EF et votre code précédent, vous devez simplement mettre à niveau vers .NET 4.5.

Si vous souhaitez également utiliser une nouvelle API, vous devrez mettre à jour une grande partie de votre code existant, mais il est toujours possible d’obtenir ObjectContext partir de DbContext et de faire fonctionner votre méthode à nouveau. Vous avez juste besoin d’utiliser cet extrait:

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

et utilisez objectContext au lieu du context dans votre code.

C’est un morceau de code très pratique. Je l’ai refactorisé un peu et c’est tellement utile que j’ai pensé le poster ici.

 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 == "Ssortingng")); 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; } } 

Et vous pouvez l’appeler comme ceci:

 GetMaxLength(x => x.CustomerName); 

En supposant que vous ayez un DbSet défini dans votre DbContext de type Client, qui a la propriété ClientName avec une longueur maximale définie.

Ceci est très utile pour des tâches telles que la création d’atsortingbuts de modèle qui définissent la longueur maximale d’un champ de texte sur la longueur maximale du champ de la firebase database, en s’assurant toujours que les deux sont identiques.

J’ai refacturé l’exemple de mccow002 dans une classe de méthode d’extension prête pour le copier-coller:

 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 == "Ssortingng")); 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; } } 

J’ai eu le même problème et la solution est ici;

  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 };