几周前我刚刚开始了一个新项目,并决定尝试 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 属性)
这将导致创建一个新城市,而不是使用对旧城市的引用。