如何首先在 EF4 代码中将表拆分为多种类型?
我正在使用带有 EF4、CTP5 的代码优先 POCO。我有一个表,其中有很多列(超过 100 列)。我想将表拆分为多种类型(也称为“表拆分”),这样我就不必每次需要一些基本信息时都获取所有数据。
我似乎无法使用谷歌找到任何关于此的文档。我找到了对“表拆分”概念的引用,并且还了解了如何使用 EDMX 文件来完成此操作,但没有代码优先的示例。
我希望它像定义另一个实体类型并将它们关联起来一样简单,就像任何其他导航属性一样...
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
}
我这样称呼它...
return (from u in Context.Users // <-- error occurs here
where u.UserID == userID
select u).FirstOrDefault();
不幸的是,这似乎不起作用。当我执行此操作时,出现以下错误...
[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
删除 User.Details 属性会使错误消失,但随后我无法使用 EF4 的漂亮导航功能。
I am using code-first POCOs with EF4, CTP5. I've got a table with a lot of columns in it (over 100). I want to split the table into multiple types (aka "Table Splitting") so that I don't have to fetch all the data every time I want some basic information.
I can't seem to find any documentation on this using Google. I've found references to the concept, "Table Splitting", and I've also seen how to do it using an EDMX file, but no samples for code-first.
I was hoping it would be as simple as defining another entity type and relating them as you would any other navigation property like so...
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
}
And I call it like this...
return (from u in Context.Users // <-- error occurs here
where u.UserID == userID
select u).FirstOrDefault();
Unfortunately this does not seem to be working. I am getting the following error when I do this...
[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
Removing the User.Details property makes the error go away, but then I can't use the nifty navigation features of EF4.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用复杂类型是将表映射到多种类型的唯一方法。但是,Code First(以及一般的 EF)不支持复杂类型的延迟/延迟加载。换句话说,每次从数据库读取实体时,EF 都会填充复杂类型:
实现大表延迟加载的唯一方法是将其真正拆分为多个表,然后您可以使用一对一一个关联将其映射回多个实体。
有关 EF Code First CTP 中复杂类型的更多信息,请查看本文:
EF Code First CTP5 中的关联:第 1 部分 – 复杂类型
Using Complex Types is the only way you can map a table to multiple types. However, Code First (and EF in general) does NOT support lazy/Deferred loading for complex types. In other words, EF will always populate the complex type each time you read the entity from the database:
The only way you can achieve lazy loading for your big table is by really splitting it into multiple tables and then you can use one-to-one associations to map it back to multiple entities.
For more info regarding Complex Types in EF Code First CTP, take a look at this article:
Associations in EF Code First CTP5: Part 1 – Complex Types
我知道这个问题已经一年多了,但是 EF Code First 同时支持表拆分和延迟加载。
您的模型应该是这样的:
延迟加载(和急切加载)应该按预期工作。
则表拆分有效
I know this question is more than a year but EF Code First supports table splitting and lazy loading at the same time.
Your model should be like this:
Lazy loading (and eager loading) should work as expected.
Its important to note that table splitting works if
我想里诺提出的答案是一个更好的答案。尽管最终你实现了同样的目标。但在第二个例子中,它的目的是做完全相同的事情。当您由于第 3 方代码而无法应用 [ComplexType] 或您有该类型的列表时,第一个可能会出现问题。
使用第二个或如 Julia Lerman 书中的 Fluent API(将“People”表拆分为“Person”和“PersonPhoto”实体)。
I guess the answer suggested by Rino is a better one. Though in the end you achieve same thing. But in the case of second one it's meant to do the exact same thing. First one can have problem when you cannot have apply [ComplexType] due to 3rd party code or you have a list of that type.
Use the second one or as in Fluent APIs as from Julia Lerman's book (splitting "People" table into "Person" and "PersonPhoto" entities.