5

几周前我刚刚开始了一个新项目,并决定尝试 EF Code First,我之前使用过 NHIbernate,我喜欢从 MS 获得一个现成的 ORM 的想法,到目前为止它很棒 -直到我开始制作复杂的物体。

我的项目层如下: Azure WCF 角色 - 使用 EF Code First 处理 DAL。Azure WebSite Role with MVC 4 with Knockout - 处理客户端。(我为将来需要从不同平台访问服务的情况创建了 WCFRole)

这是我遇到问题的非常基本的 EF Code First 设计: - 我只在服务和站点之间传输 DTO,并制作了一个通用映射器来映射内部 DTO(如果存在)。- 我有一个 City 表和一个带有 City 属性的 Address 对象(我们需要 City 作为特殊功能的属性,而不仅仅是名称)

客户知道城市列表,并返回一个带有现有城市的新地址当我尝试添加新地址时,使用旧现有城市的数据创建了一个新城市,我已经知道会发生这种情况,因为 EF 没有'不知道如何合并断开的对象,并且从我读到的内容不支持任何合并能力,并且简单而不那么舒服的解决方案只是管理对象状态-将城市对象状态更改为未更改。

但是用大型复杂的数据库设计来处理这个听起来很可怕

我的问题 - 处理这个问题的最佳实践/简单方法是什么?我考虑过这样的解决方案 - 覆盖所有对象的 SaveChanges 方法,如果 ID 不是 null/0/其他约定将其从已添加更改为未更改 - 可以完成此解决方案吗?

我的第二个问题 - 因为我对 NHibernate(连接对象)有很多经验 - 我想知道 NHibernate 对此有何看法?我在某处读到 NHibernate 确实具有 AutoMagic Merge 功能来重新连接断开连接的复杂对象,这是真的吗?我的基本断开连接的地址-> 城市设计将与 AutoMagic 合并一起使用吗?使用它的后果是什么?

非常感谢 :)

更新:该问题的简化代码。

public class Address
{
    public int ID { get; set; }

    public virtual City City { get; set; }
}

public class City
{
    public int ID { get; set; }

    public string Name { get; set; }
    public virtual Zone Zone { get; set; }
}

public class MyContext : DbContext
{
    public MyContext() : base("TransportService") { }

    public virtual DbSet<City> Cities { get; set; }
    public virtual DbSet<Address> Addresses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Address>()
            .HasRequired(x => x.City)
            .WithMany().WillCascadeOnDelete(true);

    }
}

添加新地址:

    public void Add(AddressDto address)
    {
        using (var context = new MyContext())
        {
            context.Addresses.Add(address.FromDto<Address>());

            context.SaveChanges();
        }
    }

“FromDto”是通用 Mapper 扩展,它使用所有信息创建新地址,包括城市(和 City.ID 属性)

这将导致创建一个新城市,而不是使用对旧城市的引用。

4

1 回答 1

3

我发现 EF 没有自动合并功能,目前它们的合并功能只有手动合并,而且只有在 Context 对象在内存中具有该对象的所有依赖项时它才会起作用。

处理多级断开的对象并手动重新连接它们需要大量工作,并且可能会导致非常奇怪且难以处理的错误(就像问题中所说的那样,因为没有合并而创建了新城市,所以它只是创建了一个新的,即使它有一个 ID)

所以现在 - Nhibernate 赢得了这场战斗,Nhibernate 有一个自动合并功能,如果你断开连接的对象有一个 ID,它会尝试合并它,并成功(根据我的经验)与EF,但这是值得的麻烦。

于 2013-08-06T16:55:05.227 回答