1

Issue in passing DbContext to another method i.e. for e.g:

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.


    }
}

Question: Why does when DbContext is passed to another method internally calls for all the data i.e. in dbContext.Customers.Local has all the Data in the Database in First-Level Cache ?

Question: How to Pass DbContext from one Method to Another (without creating above given issue) ?

This is Creating problem related to modification of the Data i.e. DeleteCustomer will fail over. Now, if the code in the DeleteOrderRelatedData, is merged into the DeleteCustomer function, it works fine.

I added a Logs for the dbContext , and dbContext while passing it to the Function internally is calling all the Select queries related to the different Queries..

For more details, please check this Video out : Link

Tools being used :

  1. Entity Framework 6.0
  2. System.Data.Sqlite
  3. PostSharp for MethodBoundary Aspect.
bhuvin
  • 1,382
  • 1
  • 11
  • 28
  • As @wardy says, the context doesn't spontaneously load data. It doesn't suddenly acquire data when it's passed to a method. If you check, you'll see It's got all the data *before* passing it. Maybe you should monitor executed SQL while debugging the process. – Gert Arnold Mar 16 '16 at 22:01
  • @GertArnold : please check the video http://screencast.com/t/1csUc22eA4Jk out. It demonstrates the problem. – bhuvin Mar 17 '16 at 10:22
  • Can't believe it. But are you sure it's not a debugger artifact? Does it also happen when you just run the program? And what does that squiggly underneath `Customer` tell? – Gert Arnold Mar 17 '16 at 18:34
  • @GertArnold : It was occuring just by passing the DbContext to another function. Check the answer out given by me ; Which actually created the Problem. – bhuvin Mar 18 '16 at 10:45

2 Answers2

2

Sounds like your problem is something to do with cascading deletions but the wording is difficult to understand ...

The statement in your question ...

DbContext is passed to another method internally calls for all the data

... DbContexts don't just "go and get all data" automatically, you must be triggering something that's causing it.

It sounds to me like when you are deleting your customer object EF you are manually implementing the code for a cascading delete when what you should perhaps do is just add that to the model and then remove the customer object negating the need for all this extra logic.

In other words you have said / are trying to say "when a customer is deleted, also find and remove the customers related orders".

In the code sample above you do ...

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

This is purely getting the orders by executing a "select * from orders where customerid = customer.Id"

then in the method you define below that ...

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

... it looks like you then want to further delete all the addresses for the order. Although you don't appear to be calling that method in the sample above.

Instead you can do something like this to have EF worry about the children and grandchildren deletions for you all in the db ...

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

Cascading deletes with Entity Framework - Related entities deleted by EF

The Microsoft documentation for this is here ...

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

EDIT:

My answer was based on what I knew EF would do out of the box, it seems that the actual problem was caused by a component not mentioned in the question, the problem was not about performing a heirarchy of actions as I had interpreted it was in fact about solving the issue of how another third party component was adversely affecting the EF behaviour.

In repsonse to the question:

How to Pass DbContext from one Method to Another (without creating above given issue) ?

... Just do it as passing a context between 2 methods will not in its own right cause the problem you were having.

...

It seems that answering this question correctly was impossible :(

Community
  • 1
  • 1
War
  • 8,539
  • 4
  • 46
  • 98
0

Issue was due to : I was using PostSharp, to Log the Traces using OnMethodBoundaryAspect. Now this was using Arguments internally. Since while Logging, it was serializing the Arguments, And this was creating the Problem.

bhuvin
  • 1,382
  • 1
  • 11
  • 28