实体框架 - 多项目支持

Ton*_*nyB 2 c# nhibernate entity-framework castle-activerecord

我正在寻找将大型项目迁移到Entity Framework 4.0,但我不确定它是否可以处理我的继承方案.

我有几个项目继承自"main"项目中的对象.这是一个示例基类:

 namespace People
{
    public class Person
    {
        public int age { get; set; }
        public String firstName { get; set; }
        public String lastName { get; set; }

    }
}
Run Code Online (Sandbox Code Playgroud)

和其中一个子类:

namespace People.LawEnforcement
{
    public class PoliceOfficer : People.Person
    {
        public string badgeNumber { get; set; }
        public string precinct { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是项目布局的样子:

People - People.Education - People.LawEnforcement http://img51.imageshack.us/img51/7293/efdemo.png

该应用程序的一些客户将使用People.LawEnforcement中的类,其他用户将使用People.Education,有些将使用两者.我只发运用户需要的组件.因此,Assembles有点像插件,因为它们为核心应用程序添加了功能.

反过来,实体框架是否支持这种情况?

基于这个问题,我认为这样的事情可能有用:

ctx.MetadataWorkspace.LoadFromAssembly(typeof(PoliceOfficer).Assembly);
Run Code Online (Sandbox Code Playgroud)

但即使它有效,它接缝也好像我的EDMX文件需要知道所有项目.我宁愿每个项目都包含该项目中类的元数据,但我不确定这是否可行.

如果实体框架无法做到这一点,那还有另一种解决方案(NHibernate,Active Record等)吗?

Ale*_*mes 5

是的,这是可能的,使用您已经找到的LoadFromAssembly(..)方法.

...但只有每种不同类型的客户端应用程序都有专门的模型(即EDMX)时,它才会起作用.

这是因为EF(以及大多数其他ORM)需要模型中每个实体的类,因此如果某些客户端不了解某些类,则需要没有相应实体的模型 - 即每个方案的自定义EDMX .

为了更容易为每个客户端应用程序创建一个新模型,如果我是你,我会按照我的博客上列出最佳实践使用Code-Only,以便轻松获取实际需要的模型片段需要.

希望这可以帮助

亚历克斯


Cra*_*ntz 5

亚历克斯是正确的(+1),但我强烈建议你重新考虑你的模型.在现实世界中,警察不是一个人的子类型.相反,它是该人就业的一个属性.我认为程序员经常倾向于过度强调继承而牺牲面向对象设计中的组合,但在O/R映射中尤其有问题.请记住,对象实例只能有一种类型.当该对象存储在数据库中时,实例只能在多个应用程序会话中存在该类型.如果一个人有两份工作,如警察和老师,怎么办?也许这种情况不太可能,但一般问题比你想象的更常见.

与您的问题更相关,我认为您可以通过使您的映射实体模型更通用,以及您的实体而非实体本身的特定于应用程序的数据投影来解决您手头的实际问题.考虑以下实体:

public class JobType
{
    public Guid Id { get; set; }
    // ...
}

public class Job 
{
    public JobType JobType { get; set; }
    public string EmployeeNumber { get; set; }
}

public class Person
{
    public EntityCollection<Job> Jobs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在您的执法应用程序可以:

var po = from p in Context.People
         let poJob = p.Jobs.Where(j => j.JobType == JobType.PoliceOfficerId).FirstOrDefault()
         where poJob != null
         select new PoliceOfficer
         {
             Id = p.Id,
             BadgeNumber = poJob.EmployeeNumber
         };
Run Code Online (Sandbox Code Playgroud)

哪里PoliceOfficer只是一个POCO,而不是任何类型的映射实体.

通过这种方式,您已经实现了拥有通用数据模型的目标,但在单独的项目中具有"特定于作业类型"的元素.