【问题标题】:How to pass DbContext (EntityFramework SqlConnection) to another Method?如何将 DbContext (EntityFramework SqlConnection) 传递给另一个方法?
【发布时间】:2016-03-16 10:50:40
【问题描述】:

将 DbContext 传递给另一个方法的问题,例如:

public bool MarkCustomerForDelete(Customer customerObj)
{
        using(var dbContext = new MyContext())
        {
            using(var dbTransaction = dbContext.Database.BeginTransaction())
            {

                //Clear all orders for the Given Customers          
                var orderList = dbContext.Orders.Where(x=>x.id == customerObj.OrderId).ToList();

                CommonLogicMethod(dbContext, orderList);

                //Logic 
                customerObj.Status = "Deleted";
// The Modification will fail over due to the Customer Object for that object is already attached to the DbContext with Previous Values
                dbContext.Entry(customerObj).State = EntityState.Modified;

                dbContext.SaveChanges();
                dbTransaction.Commit()
                return true;
            }
        }
}
public void DeleteOrderRelatedData(MyContext dbContext, List<Orders> orderList)
{
    foreach(var entity2 in entity2List)
    {
        var OrderAddresses = dbContext.OrderAddresses.Where(x=>x.Id == entity2.Id).ToList();
        //Now if here the dbContext has 100 Entities (Tables)
        //It internally Enumerates all the entities in the Local cache i.e. dbContext.Coupons.Local has all the Records from the DB in the Local present.


    }
}

问题:为什么当 DbContext 被传递给另一个方法时,内部调用了所有数据,即 dbContext.Customers.Local 中的所有数据都在一级缓存中?

问题:如何将 DbContext 从一种方法传递到另一种方法(不创建上述问题)?

这是创建与修改数据相关的问题,即 DeleteCustomer 将故障转移。 现在,如果将 DeleteOrderRelatedData 中的代码合并到 DeleteCustomer 函数中,它就可以正常工作了。

我为 dbContext 添加了一个日志,而 dbContext 在内部将其传递给函数时正在调用与不同查询相关的所有 Select 查询..

欲了解更多详情,请观看此视频:Link

正在使用的工具:

  1. 实体框架 6.0
  2. System.Data.Sqlite
  3. 用于 MethodBoundary Aspect 的 PostSharp。

【问题讨论】:

  • 正如@wardy 所说,上下文不会自发加载数据。当它被传递给一个方法时,它不会突然获取数据。如果您检查,您会看到它在 传递它之前获得了所有数据。也许你应该在调试进程的同时监控执行的 SQL。
  • @GertArnold:请查看视频screencast.com/t/1csUc22eA4Jk。它说明了问题。
  • 不敢相信。但是您确定它不是调试器工件吗?只是运行程序时也会发生这种情况吗? Customer 下方的波浪线说明了什么?
  • @GertArnold :它只是通过将 DbContext 传递给另一个函数而发生的。检查我给出的答案;这实际上造成了问题。

标签: c# entity-framework sqlite entity-framework-6 system.data.sqlite


【解决方案1】:

听起来您的问题与级联删除有关,但措辞难以理解......

你的问题中的陈述......

DbContext 被传递给另一个方法,内部调用所有 数据

... DbContexts 不只是自动“去获取所有数据”,您必须触发一些导致它的东西。

在我看来,当您删除客户对象 EF 时,您正在手动实现级联删除的代码,而您可能应该做的只是将其添加到模型中,然后删除客户对象,从而否定所有需要这个额外的逻辑。

换句话说,您已经说过/正在尝试说“当删除客户时,还要查找并删除与客户相关的订单”。

在上面的代码示例中,您可以...

//Clear all orders for the Given Customers          
var orderList = dbContext.Orders.Where(x=>x.id == customerObj.OrderId).ToList();

这纯粹是通过执行“select * from orders where customerid = customer.Id”来获取订单

然后在你下面定义的方法中...

public void DeleteOrderRelatedData(MyContext dbContext, List<Orders> orderList)

...看起来您想进一步删除订单的所有地址。尽管您似乎没有在上面的示例中调用该方法。

相反,您可以这样做让 EF 担心数据库中的所有子孙删除...

Entity Framework (EF) Code First Cascade Delete for One-to-Zero-or-One relationship

Cascading deletes with Entity Framework - Related entities deleted by EF

Microsoft 文档在这里 ...

https://msdn.microsoft.com/en-gb/data/jj591620.aspx

编辑:

我的回答是基于我知道 EF 会开箱即用的做法,看来实际问题是由问题中未提及的组件引起的,问题不在于执行我所解释的一系列操作事实上,它是关于解决另一个第三方组件如何对 EF 行为产生不利影响的问题。

针对这个问题:

如何将 DbContext 从一种方法传递到另一种方法(不创建上述问题)?

...只是这样做,因为在 2 个方法之间传递上下文本身不会导致您遇到的问题。

...

看来要正确回答这个问题是不可能的:(

【讨论】:

  • 如前所述,这与此处无关。
  • *1 为答案,花时间回答它!
【解决方案2】:

问题是由于: 我使用 PostSharp,使用 OnMethodBoundaryAspect 记录跟踪。 现在这是在内部使用参数。 因为在记录时,它正在对参数进行序列化,这就造成了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    相关资源
    最近更新 更多