gpt4 book ai didi

c# - Entity Framework 导航属性在建立新的 DbContext 之前不加载

转载 作者:行者123 更新时间:2023-11-30 12:24:40 25 4
gpt4 key购买 nike

我对 EF 还是比较陌生,所以如果我遗漏了一个明显的概念,请原谅我。

让我看看我是否可以简化这个...老问题在编辑历史中,但我想我可以提炼出来:

FWIW,DbContextPER REQUEST,而不是static,这就是第一个示例有效的原因。 此时不在 Controller 上使用 DI/IoC。

public class OrdersController : ApiController {
private MyDbContext db = new MyDbContext();

//controller methods....

protected override void Dispose(bool disposing) {
db.Dispose();
}
}

有效(2 个单独的请求):

//request 1: client code sends in a new order to be added to db
public Order Post([FromBody]Order order) {
db.Orders.Add(order);
db.SaveChanges();

return order;
}

//request 2: someone punches a button to send an email to CS about this order
public void NotifyCustomerService(int orderid) {
var order = db.Orders.Find(orderid);
//do email code here
}

损坏(单个请求):

//request: client code sends in a new order to be added to db AND notifies CS at same time
public Order Post([FromBody]Order order) {
db.Orders.Add(order);
db.SaveChanges();

//notify CS via email here (nav properties are not populating)

return order;
}

有效(单个请求)(但我知道这是一种糟糕的做法):

//request: client code sends in a new order to be added to db AND notifies CS at same time (using a new dbcontext in the notification code)
public Order Post([FromBody]Order order) {
db.Orders.Add(order);
db.SaveChanges();

using(var db2 = new MyDbContext()) {
var sameOrderWTF = db.Orders.Find(order.ID);
//notify CS via email using sameOrderWTF instance here (nav properties ARE populating)
}
return order;
}

所以,在我看来,向上下文添加一个新的前所未见的实体,然后尝试获取它的导航属性来填充,会产生一些副作用。但是如果你创建一个新的 DbContext ......即使在同一个请求中,它也必须直接访问该实体的数据库,而不是使用内存中的副本,这样导航属性就会神奇地工作。这就是让我难过的部分。

工作解决方案

//request: client code sends in a new order to be added to db AND notifies CS at same time
public Order Post([FromBody]Order o) {
Order order = db.Orders.Create();
db.Orders.Add(order);

//copy values from input to proxy instance
db.Entry(order).CurrentValues.SetValues(o);

//copy input lines to proxy instance (same process as order for each line)
o.OrderLines.ToList().ForEach(l => {
var line = db.OrderLines.Create();
db.OrderLines.Add(line);
db.Entry(line).CurrentValues.SetValues(l);
order.OrderLines.Add(line);
});

db.SaveChanges();

//notify CS via email here (nav properties are not populating)

return order;
}

因此,虽然我们会考虑回答这个问题(感谢 Uber Bot),但比起我在 ASP.NET MVC 和 EF 上的其他(公认的短)经历,完成所有这些似乎更费力。我想也许我应该使用 ViewModels 并将 VM 属性映射到代理实例,而不是尝试直接使用 EF 类,但我真的看不到像这样的简单调用的好处。

最佳答案

您的新 Order 实体实例未被代理包装,因此延迟加载将不起作用。

您可以强制上下文加载导航属性。

db.Entry(order).Reference(o => o.YouProperty).Load();

或者您可以使用上下文的工厂来创建一个实例来克服这个问题。

db.Orders.Create();

A proxy instance will not be created if you create an instance of an entity using the new operator. This may not be a problem, but if you need to create a proxy instance (for example, so that lazy loading or proxy change tracking will work) then you can do so using the Create method of DbSet.

https://msdn.microsoft.com/en-us/data/jj592886.aspx

关于c# - Entity Framework 导航属性在建立新的 DbContext 之前不加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33134697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com