2

I currently use a general repositry class that can update only a single table like so

public abstract class MyRepository<T> : IRepository<T>
        where T : class
{


    protected IObjectSet<T> _objectSet;
    protected ObjectContext _context;

    public MyRepository(ObjectContext Context)
    {
        _objectSet = Context.CreateObjectSet<T>();
        _context = Context;
    }


    public IQueryable<T> GetAll()
    {
        return _objectSet.AsQueryable();
    }

    public IQueryable<T> Find(Expression<Func<T, bool>> filter)
    {
        return _objectSet.Where(filter);
    }

    public void Add(T entity)
    {
        _objectSet.AddObject(entity);
        _context.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Added);
        _context.SaveChanges();
    }

    public void Update(T entity)
    {
        _context.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Modified);
        _context.SaveChanges();
    }

    public void Delete(T entity)
    {
        _objectSet.Attach(entity);
        _context.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Deleted);
        _objectSet.DeleteObject(entity);
        _context.SaveChanges();
    }

}

For every table class generated by my EDMX designer I create another class like this

public class CustomerRepo : MyRepository<Customer>
{
    public CustomerRepo (ObjectContext context)
        : base(context)
    {

    }
}

for any updates that I need to make to a particular table I do this:

Customer CustomerObj = new Customer();
CustomerObj.Prop1 = ...
CustomerObj.Prop2 = ...
CustomerObj.Prop3 = ...
CustomerRepo.Update(CustomerObj);

This works perfectly well when I am updating just to the specific table called Customer. Now if I need to also update each row of another table which is a child of Customer called Orders what changes do I need to make to the class MyRepository. Orders table will have multiple records for a Customer record and multiple fields too, say for example Field1, Field2, Field3.

So my question is: 1.) If I only need to update Field1 of the Orders table for some rows based on a condition and Field2 for some other rows based on a different condition then what changes I need to do?

2.) If there is no such condition and all child rows need to be updated with the same value for all rows then what changes do I need to do?

Thanks for taking the time. Look forward to your inputs...

user20358
  • 14,182
  • 36
  • 114
  • 186

1 Answers1

1

Your primary issue is that you are attempting to update a disconnected entity (i.e. var myCustomer = new Customer()) without attaching it to the data context. See this answer for details on how to attach disconnected entities. In your case, I think this could get complex, because not only would the parent entity need to be attached, but all child entities as well.

My suggestion, in your case, is to perform updates against entities that are retrieved from the context first, and therefore will already be attached to it. In this case, these entities will track changes themselves. You will have no need to attach the entities to your context or call _context.ObjectStateManager.ChangeObjectState. Again, take a look at the same answer I mentioned earlier for an example that performs an update on attached entities. Once the parent object is loaded, you just apply any changes to it and its children, and then call the SaveChanges method on the context once its all said and done.

Note: By default, EF will lazy load any child relationships (i.e child objects, collections, etc). However, in some cases, you may wish to explicitly/eager load the child objects at the same time that the parent is loaded, rather than lazy loading (you can find documentation here).

Community
  • 1
  • 1
Justin Holzer
  • 2,326
  • 2
  • 22
  • 22