LINQ track changes
HI, Wit linq i populate a generic list in DAL. then in UI layer the user removes and updates items from the list. Is it possible for LINQ to k开发者_如何学Pythoneep track of the changes without having to write code to check which items have been removed and deleting them/adding new items and updating others etc. it seems that this is not possible when using datacontext which popluates the list and seperate datacontext which is responsible fo SubmitChanges. Any help appreciated.
thanks Niall
If you are using Linq.DataContext
then it does indeed keep track of changes for you.
The function to reference is System.Data.Linq.DataContext.GetChangeSet. Although GetChangeSet
can be called at any time it would be good to reference the Remarks section in the MSDN documentation.
You can check / take action on submit...
Here is a quick example of how you can override SubmitChanges
on a DataContext
and take actions at that point.
The example shows that you can modify the data before final submit, you can also keep track and take special action when specific members are updated:
namespace ExampleProject1.Models
{
public partial class ExampleProject1DataContext
{
public override void SubmitChanges(ConflictMode failureMode)
{
ManangeAndProcessChangeSet(base.GetChangeSet());
base.SubmitChanges(failureMode);
}
private void ManangeAndProcessChangeSet(ChangeSet changeSet)
{
DateTime now = DateTime.UtcNow;
if (changeSet.Inserts.Count > 0)
{
ProcessInserts(changeSet.Inserts, now);
}
if (changeSet.Updates.Count > 0)
{
ProcessUpdates(changeSet.Updates, now);
}
if (changeSet.Deletes.Count > 0)
{
ProcessDeletes(changeSet.Deletes, now);
}
}
private void ProcessInserts(IList<object> list, DateTime now)
{
IEnumerable<Cake> cakes = list.OfType<Cake>();
IEnumerable<Topping> toppings = list.OfType<Topping>();
// Update the created and modified times.
foreach (Cake cake in cakes)
{
cake.Guid = Guid.NewGuid();
cake.CreatedDateTime = now;
cake.ModifiedDateTime = now;
}
foreach (Topping topping in toppings)
{
topping.Guid = Guid.NewGuid();
topping.CreatedDateTime = now;
topping.ModifiedDateTime = now;
}
}
private void ProcessUpdates(IList<object> list, DateTime now)
{
IEnumerable<Cake> cakes = list.OfType<Cake>();
IEnumerable<Topping> toppings = list.OfType<Topping>();
// Update the created and modified times.
foreach (Cake cake in cakes)
{
ProcessUpdates(cake, now);
}
foreach (Topping topping in toppings)
{
topping.ModifiedDateTime = now;
}
}
private void ProcessDeletes(IList<object> list, DateTime now)
{
IEnumerable<Cake> cakes = list.OfType<Cake>();
IEnumerable<Topping> toppings = list.OfType<Topping>();
// Could create tasks here to delete associated stored files for cakes and toppings.
}
private bool ProcessUpdates(Cake cake, DateTime now)
{
bool modified = false;
ModifiedMemberInfo[] mmi = context.Cakes.GetModifiedMembers(cake);
foreach (ModifiedMemberInfo mi in mmi)
{
switch (mi.Member.Name)
{
case "CountOfItemsSold":
// Exclude from updating the modified date.
break;
case "IsExpired":
if ((bool)mi.CurrentValue)
{
cake.ExpiredDateTime = now;
}
else
{
cake.ExpiredDateTime = null;
}
modified = true;
break;
default:
modified = true;
break;
}
}
if (modified)
{
cake.ModifiedDateTime = now;
}
return modified;
}
}
}
If you have a N-Tier application, this will not be possible, because you will be doing your updates, deletes and inserts in a disconnected fashion.
In other words, one data context will be used to create the list, the entities will get passed to the client, via WCF or some other mechanism, and then sent back to the DAL and another data context will be used to do the updates.
It is unclear what edit mechanism you are using, but if multiple DataContext
are involved, yes: you must tell the submitting data-context about the delete (via DeleteOnSubmit
). Of course, it needs to know about every change - otherwise it won't know to change the database.
精彩评论