Here is the situation in which I use EF.
The repository receives an instance of A and returns to the presentation level (i.e. MVC controllers)
Controllers change some properties of instance A and return it for storage.
Before continuing, I need to find out what changes have been made to the object and check if the change is allowed or not.
To compare the change, I need an old instance from the database.
But EF returns the same dirty instance, so I cannot compare them.
What I tried to do: Class structure
public Class A { public BB {get;set;} } public class B { public ICollection<A> As {get;set;} public C c { get; set;} } public class C { }
B and C are mapped to the same database.
Although this is because EF keeps track of the old instance, and since saving is not yet called on the instance, it therefore returns the same inatce back.
So, I turned off lazy loading, the proxy gene, and returned the objects as invisible to the repository.
Now EF returns a new record from the database, but if you change a property to A, then in the B-collection A it only loads the instance of A, which I changed, and not the entire collection.
When If I want to create a new A and save, I do the following
B b = GetSomeOldB (); A a = new A (); aB = b a.Save ();
So I essentially add a new A to the context and call SaveChanges.
Ef returns and excludes that "Cannot pass C to B".
Basically, all I want to do is get the old graph of the object from the context, when I ask, compare it with the dirty one, letting the dirt save.
It would be very helpful to help !!
Here is the final solution: 1. Returned to creating the tracking and proxy server 2. Get the original copy from EF. 3. Wrote this general method for hydrating a new instance of an object
public ICollection<T> GetOriginalCollection<T>(ICollection<T> changedCollection) where T : class { ICollection<T> original = new Collection<T>(); foreach (var item in changedCollection) { //Dont return the newly added ones to the original collection if (_context.Entry(item).State != EntityState.Added){ original.Add(GetOriginal(item)); } } return original; } public T GetOriginal<T>(T changedEntity) where T : class { Func<DbPropertyValues, Type, object> getOriginal = null; getOriginal = (originalValues, type) => { object original = Activator.CreateInstance(type, true); foreach (var ptyName in originalValues.PropertyNames) { var property = type.GetProperty(ptyName); object value = originalValues[ptyName];
source share