¿Cómo puedo dividir una tabla en múltiples tipos de código EF4 primero?
-
12-10-2019 - |
Pregunta
Estoy utilizando POCOs de código primero con EF4, CTP5. Tengo una tabla con una gran cantidad de columnas en ella (más de 100). Quiero dividir la tabla en múltiples tipos (también conocido como "Tabla división") para que yo no tengo que buscar todos los datos cada vez que quiero algo de información básica.
Me parece que no puede encontrar ninguna documentación sobre este uso de Google. He encontrado referencias al concepto de "división de tablas", y también he visto cómo hacerlo utilizando un archivo EDMX, pero no hay muestras de código en primer lugar.
Tenía la esperanza de que sería tan simple como definir otro tipo de entidad y relacionándolas como lo haría con cualquier otra propiedad de navegación como tal ...
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
}
Y la llamo así ...
return (from u in Context.Users // <-- error occurs here
where u.UserID == userID
select u).FirstOrDefault();
Por desgracia, esto no parece estar funcionando. Estoy recibiendo el siguiente error cuando hago esto ...
[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
La eliminación de la propiedad User.Details hace que el error desaparezca, pero entonces no se puede utilizar la navegación ingenioso cuenta de EF4.
Solución
Con tipos complejos es la única manera que puede asignar una mesa para múltiples tipos. Sin embargo, el Código First (EF y en general) no soporta la carga diferida / diferido para este tipo de complejos. En otras palabras, EF siempre rellenará el tipo complejo cada vez que lea la entidad a partir de la base de datos:
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 única manera de lograr la carga diferida para su mesa grande es realmente por su división en varias tablas y luego se puede utilizar uno-a-uno asociaciones para mapear de nuevo a múltiples entidades.
Para obtener más información con respecto a tipos complejos en Código EF primer CTP, echar un vistazo a este artículo:
Asociaciones en Código EF Primera CTP5: Parte 1 - tipos complejos
Otros consejos
Sé que esta pregunta es más de un año, pero Código EF primeros soportes división de tablas y carga diferida al mismo tiempo.
Su modelo debe ser como este:
[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; }
}
Lazy carga (carga y ansiosos) debería funcionar como se espera.
Es importante señalar que las obras tabla de división si
- entidades tienen 1-a-1 relación, y
- Las entidades comparten la misma clave
supongo que la respuesta sugerida por Rino es una mejor. Aunque al final a lograr lo mismo. Pero en el caso de la segunda, que está destinado a hacer exactamente lo mismo. En primer lugar uno puede tener un problema cuando no se puede aplicar has [ComplexType] debido al código de tercera parte o si tiene una lista de ese tipo.
Usar el segundo o como en las API de fluido como del libro de Julia Lerman (splitting "Personas" tabla en "Persona" y entidades "PersonPhoto".
modelBuilder.Entity<Person>().ToTable("People");
modelBuilder.Entity<PersonPhoto>().ToTable("People");