我正在考虑将一个大型项目迁移到 Entity Framework 4.0,但不确定它是否可以处理我的继承场景。
我有几个项目继承自“主”项目中的一个对象。这是一个示例基类:
namespace People
{
public class Person
{
public int age { get; set; }
public String firstName { get; set; }
public String lastName { get; set; }
}
}
和子类之一:
namespace People.LawEnforcement
{
public class PoliceOfficer : People.Person
{
public string badgeNumber { get; set; }
public string precinct { get; set; }
}
}
这就是项目布局的样子:
People - People.Education - People.LawEnforcement http://img51.imageshack.us/img51/7293/efdemo.png
该应用程序的一些客户将使用 People.LawEnforcement 和其他用户将使用 People.Education,有些人会同时使用两者。我只运送用户需要的组件。因此,组合件的行为有点像插件,它们向核心应用程序添加功能。
实体框架中是否有支持这种情况的方法?
基于这个问题我我认为这样的东西可能会起作用:
ctx.MetadataWorkspace.LoadFromAssembly(typeof(PoliceOfficer).Assembly);
但即使它起作用了,我的 EDMX 文件似乎也需要了解所有项目。我宁愿让每个项目都包含该项目中类的元数据,但我不确定这是否可能。
如果实体框架无法做到这一点,是否还有其他可行的解决方案(NHibernate、Active Record 等)?
I am looking into migrate a large project to Entity Framework 4.0 but am not sure if it can handle my inheritance scenario.
I have several projects that inherit from an object in the “main” project. Here is a sample base class:
namespace People
{
public class Person
{
public int age { get; set; }
public String firstName { get; set; }
public String lastName { get; set; }
}
}
and one of the sub-classes:
namespace People.LawEnforcement
{
public class PoliceOfficer : People.Person
{
public string badgeNumber { get; set; }
public string precinct { get; set; }
}
}
And this is what the project layout looks like:
People - People.Education - People.LawEnforcement http://img51.imageshack.us/img51/7293/efdemo.png
Some customers of the application will use classes from the People.LawEnforcement and other users will use People.Education and some will use both. I only ship the assembles that the users will need. So the Assembles act somewhat like plug-ins in that they add features to the core app.
Is there anyway in Entity Framework to support this scenario?
Based on this SO question I'm think something like this might work:
ctx.MetadataWorkspace.LoadFromAssembly(typeof(PoliceOfficer).Assembly);
But even if that works then it seams as if my EDMX file will need to know about all the projects. I would rather have each project contain the metadata for the classes in that project but I'm not sure if that is possible.
If this isn't possible with entity framework is there another solution (NHibernate, Active Record, etc.) that would work?
发布评论
评论(2)
是的,这是可能的,使用您已经找到的 LoadFromAssembly(..) 方法。
...但只有当您为每种不同类型的客户端应用程序拥有专门的模型(即 EDMX)时,它才会起作用。
这是因为 EF(以及大多数其他 ORM)需要模型中的每个实体都有一个类,因此如果某些客户端不了解某些类,您将需要一个没有相应实体的模型 - 即针对每个场景的自定义 EDMX 。
为了更轻松地为每个客户端应用程序创建新模型,如果我是您,我会使用 仅代码 遵循 最佳实践放在我的博客上,以便轻松地仅获取您实际需要的模型片段需要。
希望这对
亚历克斯有帮助
Yes this is possible, using the LoadFromAssembly(..) method you've already found.
... but it will only work if you have an specialized model (i.e. EDMX) for each distinct type of client application.
This is because EF (and most other ORMs) require a class for each entity in the model, so if some clients don't know about some classes, you will need a model without the corresponding entities -- i.e. a customized EDMX for each scenario.
To make it easier to create a new model for each client application, if I was you I'd use Code-Only following the best practices laid out on my blog, to make it easy to grab only the fragments of the model you need actually need.
Hope this helps
Alex
亚历克斯是正确的(+1),但我强烈建议您重新考虑您的模型。在现实世界中,警察不是人的亚型。相反,它是该人就业的一个属性。我认为,在面向对象的设计中,程序员经常倾向于过分强调继承,而忽视了组合,但这在 O/R 映射中尤其成问题。请记住,一个对象实例只能有一种类型。当该对象存储在数据库中时,只要实例存在,该实例就只能在多个应用程序会话中具有该类型。如果一个人有两份工作,警察和老师怎么办?也许这种情况不太可能发生,但总体问题比您想象的更常见。
与您的问题更相关,我认为您可以通过使映射的实体模型更加通用以及对实体而不是实体本身的应用程序特定数据投影来解决您手头的实际问题。考虑如下实体:
现在您的执法应用程序可以执行以下操作:
其中
PoliceOfficer
只是 POCO,而不是任何类型的映射实体。这样,您就实现了拥有通用数据模型的目标,但在单独的项目中拥有“特定于作业类型”的元素。
Alex is correct (+1), but I'd strongly urge you to reconsider your model. In the real world, a police officer is not a subtype of a person. Rather, it's an attribute of that person's employment. I think programmers frequently tend to over-emphasize inheritance at the expense of composition in object oriented design, but it's especially problematic in O/R mapping. Remember that an object instance can only ever have one type. When that object is stored in the database, the instance can only have that type for as long as it exists, across multiple application sessions. What if a person had two jobs, as a police officer and a teacher? Perhaps that scenario is unlikely, but the general problem is more common than you might expect.
More relevant to your question, I think you can solve your actual problem at hand by making your mapped entity model more generic, and your application-specific data projections on the entities rather than entities themselves. Consider entities like:
Now your law enforcement app can do:
Where
PoliceOfficer
is just a POCO, not a mapped entity of any kind.And with that you've achieved your goal of having a common data model, but having the "job type specific" elements in separate projects.