Domanda

I have an classic 3 layer project, that has these layers:

  • UI (WinForm Project)
  • BLL
  • DAL(using EF codefirst)

My entities are disconnected POCOs and I used them to pass data between layers and used them to bind to the UI controls.

I load a graph of some related entities to UI(e.g. Order with it's OrderLines and Product of each OrderLine), user may add some new entities, edit some others and delete some others entities in this graph, and then send this graph to DAL to persist this changes to DB.

I want to All these CRUD operations apply in one transaction. so, for this requirement, and because my POCOs are disconnected, I used following State enum for my BaseEntity class to keep its state in client side(all other entities inherited from BaseEntity):

public enum States
    {
        Unchanged,
        Added,
        Modified,
        Deleted
    }

In DAL, when I want to persist this changed graph of objects, because this entity graph is disconnected from DbContext, I should attach root of my graph to the created DbContext and because after attaching the root to DbContext state of all entries in the DbContext will be Added, I should sync State of each Entry in DbContext with State of entities in my graph, so I used these methods to do this:

public static EntityState ConvertState(BaseEntity.States state)
{
    switch (state)
    {
        case BaseEntity.States.Added:
            return EntityState.Added;
        case BaseEntity.States.Modified:
            return EntityState.Modified;
        case BaseEntity.States.Deleted:
            return EntityState.Deleted;
        default:
            return EntityState.Unchanged;
    }
}

public void ApplyChanges<TEntity>(TEntity root) where TEntity : BaseEntity
{
   _dbContext.Set<TEntity>().Add(root);
    foreach (var entry in _dbContext.ChangeTracker
    .Entries<BaseEntity>())
    {
        BaseEntity stateInfo = entry.Entity;
        entry.State = ConvertState(stateInfo.State);
    }
}

As you see, I am doing a lot of stuff outside of EF and do not use EF features, because my POCOs are disconnected.

Is there any way to apply these bulk CRUD scenario, without disconnecting my POCOs from DbContext?

È stato utile?

Soluzione

For disconnected POCO entities I have followed this pattern when persisting.

  • Get a connected entity graph from the db.
  • Map the disconnected graph to the connected one.
  • Persist the connected graph.

Currently you are attempting to track changes all the way up through the UI, when these changes may or may not be relevant by the time you are ready to persist, which is cumbersome at best. I have found that getting the most recent entity from the db just prior to persisting works out much better.

This also gives you the ability to check for concurrency issues when performing the mapping.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top