EF vs Nhibernate合并断开连接的对象图
本文关键字:连接 对象图 断开 合并 vs Nhibernate EF | 更新日期: 2023-09-27 18:18:56
几个星期前我刚开始一个新项目,决定给EF Code First一个尝试。我以前用过NHIbernate,我喜欢从MS获得一个现成的ORM的想法,到目前为止它还很好——直到我开始制作复杂的对象。
我的项目层次如下:Azure WCF角色-首先用EF代码处理DAL。Azure网站角色与MVC 4与Knockout -处理客户端。(我创建WCFRole是为了将来我们需要从不同的平台访问服务)
这是非常基本的EF代码第一设计,我有麻烦:-我只在服务和站点之间传输dto,并制作了一个通用映射器来映射内部dto(如果存在的话)。-我有一个城市表和一个带有城市属性的地址对象(我们需要城市作为特殊功能的属性,而不仅仅是名称)
客户端知道城市列表,并且返回一个带有现有城市的新地址当我尝试添加新地址时,一个新的城市是用旧的现有的数据创建的,我已经得到了这种情况的发生,因为EF不知道如何合并断开连接的对象,从我读到的不支持任何合并能力,而简单的不那么舒适的解决方案只是管理对象状态-将城市对象状态更改为不变。
但是用一个大而复杂的db设计来处理这个问题听起来很可怕
我的问题-处理这个问题的最佳实践/简单方法是什么?我想到的解决方案,如-覆盖SaveChanges方法通过所有对象,如果ID不是null/0/一些其他约定改变它从添加到不变-这个解决方案可以做到吗?
我的第二个问题-因为我有很多使用NHibernate(连接对象)的经验——我想知道NHibernate在这方面是怎么做的?我在某个地方读到,NHibernate确实有一个自动合并的能力,重新连接断开的复杂对象,这是真的吗?我的基本断开连接的地址->城市设计将工作开箱即用的自动合并?使用它的后果是什么?
谢谢你:)
更新:问题的简化代码。
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(和City)。ID属性)
这将导致创建一个新的城市,而不是使用对旧城市的引用。
我发现EF没有自动合并功能,他们的合并功能到目前为止只有手动合并,只有当Context对象在内存中有对象的所有依赖项时,它才会工作。
处理多层断开的对象,并手动重新连接它们是大量的工作,可能会导致非常奇怪和难以处理的bug(就像在问题中所述的新城市被创建,因为它没有合并,所以它只是创建了一个新的,即使它有一个ID)
所以现在- Nhibernate赢得了这场战斗,Nhibernate有一个自动合并功能,如果你的断开连接的对象有一个ID,它会尝试合并它,并成功(从我的经验)与EF相比,它需要更多的设置来运行东西,但这是值得的。