Comment puis-je diviser une table en plusieurs types dans le code EF4 en premier?
-
12-10-2019 - |
Question
J'utilise Poços de code-première avec EF4, CTP5. J'ai une table avec beaucoup de colonnes en elle (plus de 100). Je veux diviser la table en plusieurs types (alias « Table splitting ») pour que je ne dois pas chercher toutes les données chaque fois que je veux des informations de base.
Je ne peux pas sembler trouver une documentation sur cette aide de Google. J'ai trouvé des références au concept, « Table Splitting », et je l'ai aussi vu comment le faire en utilisant un fichier EDMX, mais pas d'échantillons pour-premier code.
J'espérais que ce serait aussi simple que la définition d'un autre type d'entité et les concernant comme tout autre propriété de navigation comme si ...
public class User
{
public int UserID { get; set; }
public string UserName { get; set; }
[ForeignKey("UserID")]
public virtual UserDetails Details { get; set; }
}
public class UserDetails
{
public int UserID { get; set; }
public string MoreData { get; set; }
[ForeignKey("UserID")]
public virtual User User { get; set; } // nice to have, but not required
}
Et je l'appelle comme ça ...
return (from u in Context.Users // <-- error occurs here
where u.UserID == userID
select u).FirstOrDefault();
Malheureusement, cela ne semble pas fonctionner. Je reçois l'erreur suivante quand je fais cela ...
[IndexOutOfRangeException: Index was outside the bounds of the array.]
System.Data.Entity.ModelConfiguration.Conventions.Edm.PropertyMaxLengthConvention.System.Data.Entity.ModelConfiguration.Conventions.Edm.IEdmConvention<System.Data.Edm.EdmAssociationType>.Apply(EdmAssociationType associationType, EdmModel model) +598
System.Data.Entity.ModelConfiguration.Configuration.EdmConventionDispatcher.Dispatch(TEdmDataModelItem item) +100
System.Data.Entity.ModelConfiguration.Configuration.EdmConventionDispatcher.VisitEdmAssociationType(EdmAssociationType item) +22
System.Data.Entity.ModelConfiguration.Edm.Services.DataModelItemVisitor.VisitCollection(IEnumerable`1 collection, Action`1 visitMethod) +267
System.Data.Entity.ModelConfiguration.Edm.Services.EdmModelVisitor.VisitAssociationTypes(EdmNamespace edmNamespace, IEnumerable`1 associationTypes) +75
System.Data.Entity.ModelConfiguration.Edm.Services.EdmModelVisitor.VisitEdmNamespace(EdmNamespace item) +91
System.Data.Entity.ModelConfiguration.Configuration.EdmConventionDispatcher.VisitEdmNamespace(EdmNamespace item) +32
System.Data.Entity.ModelConfiguration.Edm.Services.DataModelItemVisitor.VisitCollection(IEnumerable`1 collection, Action`1 visitMethod) +267
System.Data.Entity.ModelConfiguration.Edm.Services.EdmModelVisitor.VisitNamespaces(EdmModel model, IEnumerable`1 namespaces) +75
System.Data.Entity.ModelConfiguration.Edm.Services.EdmModelVisitor.VisitEdmModel(EdmModel item) +47
System.Data.Entity.ModelConfiguration.Configuration.EdmConventionDispatcher.VisitEdmModel(EdmModel item) +45
System.Data.Entity.ModelConfiguration.Configuration.ConventionsConfiguration.ApplyModel(EdmModel model) +254
System.Data.Entity.ModelConfiguration.ModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo, Boolean validateModel) +257
System.Data.Entity.ModelConfiguration.ModelBuilder.Build(DbConnection providerConnection) +172
System.Data.Entity.Internal.LazyInternalContext.CreateModel() +62
System.Lazy`1.CreateValue() +361
System.Lazy`1.LazyInitValue() +104
System.Lazy`1.get_Value() +89
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +358
System.Data.Entity.Internal.InternalContext.Initialize() +16
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +16
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +61
System.Data.Entity.Internal.Linq.InternalSet`1.get_Provider() +15
System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() +13
System.Linq.Queryable.Where(IQueryable`1 source, Expression`1 predicate) +63
TourFactory.Web.AgentWebsite.Models.Websites.WebsiteRepository.GetUser(Int32 userID) in C:\Code\hdtf\TF4\Web\AgentWebsite\Models\Websites\WebsiteRepository.cs:28
TourFactory.Web.AgentWebsite.Controllers.WebsiteController.get_Agent() in C:\Code\hdtf\TF4\Web\AgentWebsite\Controllers\WebsiteController.cs:42
TourFactory.Web.AgentWebsite.Controllers.WebsiteController.OnActionExecuting(ActionExecutingContext filterContext) in C:\Code\hdtf\TF4\Web\AgentWebsite\Controllers\WebsiteController.cs:55
System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) +39
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +81
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +61
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +305
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +830
System.Web.Mvc.Controller.ExecuteCore() +136
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +232
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +39
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +68
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +44
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +42
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +141
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +54
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +61
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +31
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +56
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +110
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8841105
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
Retrait de la propriété User.Details fait l'erreur aller, mais je ne peux pas utiliser les fonctions de navigation de nifty EF4.
La solution
Utilisation Types complexes est la seule façon que vous pouvez mapper une table à plusieurs types. Toutefois, le code premier (et EF en général) ne supporte pas le chargement paresseux / différés pour les types complexes. En d'autres termes, EF renseignera toujours le type complexe à chaque fois que vous avez lu l'entité de la base de données:
public class User
{
public int UserID { get; set; }
public string UserName { get; set; }
public UserDetails Details { get; set; }
}
[ComplexType]
public class UserDetails
{
public string MoreData { get; set; }
}
La seule façon que vous pouvez réaliser le chargement paresseux pour votre grande table est vraiment en le divisant en plusieurs tables et vous pouvez alors utiliser un à-un à la carte revenir à plusieurs entités.
Pour plus d'information concernant les types complexes dans le code EF Première CTP, jetez un oeil à cet article:
associations dans le code EF Première CTP5: Partie 1 - Types complexes
Autres conseils
Je sais que cette question est plus d'un an, mais le code EF premiers supports fractionnement de la table et le chargement paresseux en même temps.
Votre modèle doit ressembler à ceci:
[Table("UserTable")]
public class User
{
[Key, ForeignKey("Details")]
public int UserID { get; set; }
public string UserName { get; set; }
public virtual UserDetails Details { get; set; }
}
[Table("UserTable")]
public class UserDetails
{
[Key, ForeignKey("User")]
public int UserID { get; set; }
public string MoreData { get; set; }
public virtual User User { get; set; }
}
chargement Lazy (et le chargement désireux) devrait fonctionner comme prévu.
Il est important de noter que des travaux de fractionnement de table si
- Entités ont 1 à une relation, et
- Les entités partagent la même clé
Je suppose que la réponse proposée par Rino est un meilleur. Bien que à la fin vous réalisez même chose. Mais dans le cas de second il est destiné à faire exactement la même chose. Tout d'abord on peut avoir des problèmes lorsque vous ne pouvez pas avoir appliquer [ComplexType] en raison de code de 3ème partie ou si vous avez une liste de ce type.
Utilisez le deuxième ou dans les API Fluent que du livre de Julia Lerman (division « peuple » dans la table des entités « personne » et « PersonPhoto ».
modelBuilder.Entity<Person>().ToTable("People");
modelBuilder.Entity<PersonPhoto>().ToTable("People");