【发布时间】:2017-06-09 15:47:55
【问题描述】:
我正在使用 Entity Framework 6。当我将导航属性更新为一个对象,然后执行 SaveChanges(),而不是引用现有的对象时,它会在引用表中创建一个副本。
下面有一些例子:
以下示例按预期工作。它创建了一个“客户”和一个“订单”并成功地将它们关联起来:
// Homer Simpson buys some Duff beer
Console.WriteLine("Homer Simpson is buying Duff beer");
Customer customer = new Customer
{
Name = "Homer Simpson"
};
Order order1 = new Order
{
Description = "Duff Beer"
};
customer.Orders.Add(order1);
using (EFContext db = new EFContext())
{
db.Customers.Add(customer);
DisplayChanges(db);
db.SaveChanges();
}
输出
Homer Simpson is buying Duff beer
ConsoleApplication1.Objects.Customer - Added
ConsoleApplication1.Objects.Order - Added
但是,如果我尝试添加订单并关联现有客户,当我保存更改时,它会复制数据库中的客户对象以及我创建的现有订单:
// Homer Simpson buys some Duff beer
Console.WriteLine("Homer Simpson is buying Duff beer");
Customer customer = new Customer
{
Name = "Homer Simpson"
};
Order order1 = new Order
{
Description = "Duff Beer"
};
customer.Orders.Add(order1);
using (EFContext db = new EFContext())
{
db.Customers.Add(customer);
DisplayChanges(db);
db.SaveChanges();
}
// Homer Simpson buys some Buzz Cola
Console.WriteLine("\r\nHomer Simpson is buying Buzz Cola");
Order order2 = new Order
{
Description = "Buzz Cola",
Customer = customer
};
using (EFContext db = new EFContext())
{
db.Orders.Add(order2);
DisplayChanges(db);
db.SaveChanges();
}
输出
Homer Simpson is buying Duff beer
ConsoleApplication1.Objects.Customer - Added
ConsoleApplication1.Objects.Order - Added
Homer Simpson is buying Buzz Cola
ConsoleApplication1.Objects.Order - Added
ConsoleApplication1.Objects.Customer - Added
ConsoleApplication1.Objects.Order - Added
如果我设置外键而不是导航属性,则记录不会重复。但是,在这种情况下,我无法访问相关对象的属性,直到我明确加载它:
// Homer Simpson buys some Duff beer
Console.WriteLine("Homer Simpson is buying Duff beer");
Customer customer = new Customer
{
Name = "Homer Simpson"
};
Order order1 = new Order
{
Description = "Duff Beer"
};
customer.Orders.Add(order1);
using (EFContext db = new EFContext())
{
db.Customers.Add(customer);
DisplayChanges(db);
db.SaveChanges();
}
// Homer Simpson buys some donuts
Console.WriteLine("\r\nHomer Simpson is buying donuts");
Order order3 = new Order
{
Description = "Donuts",
CustomerID = 1
};
if (order3.Customer == null)
{
Console.WriteLine("Customer is null before save!");
}
else
{
Console.WriteLine("The customer is " + customer.Name + " before save!");
}
using (EFContext db = new EFContext())
{
db.Orders.Add(order3);
DisplayChanges(db);
db.SaveChanges();
}
if (order3.Customer == null)
{
Console.WriteLine("Customer is null after save!");
}
else
{
Console.WriteLine("The customer is " + customer.Name + " after save!");
}
using (EFContext db = new EFContext())
{
db.Orders.Attach(order3);
db.Entry(order3).Reference(x => x.Customer).Load();
}
if (order3.Customer == null)
{
Console.WriteLine("Customer is null after forced load!");
}
else
{
Console.WriteLine("The customer is " + customer.Name + " after forced load!");
}
输出
Homer Simpson is buying Duff beer
ConsoleApplication1.Objects.Customer - Added
ConsoleApplication1.Objects.Order - Added
Homer Simpson is buying donuts
Customer is null before save!
ConsoleApplication1.Objects.Order - Added
Customer is null after save!
The customer is Homer Simpson after forced load!
有人可以提供任何建议吗?我知道您可以手动附加和分离实体,但话虽如此,我正在处理一些非常复杂的对象。我想找到一种简单的方法来控制实体框架中的更改跟踪。
问候
彼得·迪根
【问题讨论】:
-
没有简单的方法 - 在 EF 中使用断开连接的对象图从来都不是一件容易/简单的事情。您可以尝试尝试解决该主题的GraphDiff 包。不幸的是,作者不再支持它。
标签: entity-framework entity-framework-6