2008-12-11 5 views
3

J'essaie de déterminer si des modifications ont été apportées à un objet entité particulier. Essentiellement, je veux savoir si SubmitChanges() changera réellement quelque chose. Je préférerais être en mesure de déterminer cela après l'appel de SubmitChanges(), mais cela n'a pas vraiment d'importance.Comment savoir si SubmitChanges() va réellement changer quoi que ce soit pour une entité particulière dans LINQ to SQL

Quelqu'un sait comment je ferais cela?

Répondre

1

C'est ce que je suis venu avec:

Public Function HasChanges(ByVal obj As Object) As Boolean 
    Dim cs = GetChangeSet() 
    If cs.Updates.Contains(obj) Or cs.Inserts.Contains(obj) Or cs.Deletes.Contains(obj) Then Return True 
    Return False 
End Function 
5

Jetez un oeil à la fonction GetChangeset sur votre DataContext.

+0

Mais attention pour les effets secondaires mentionnés dans l'article MSDN lié –

+0

Est-il possible de voir les changements pour un objet particulier? Il y aura probablement des changements dont je ne me soucie pas. –

2

Vous pouvez accéder directement aux changements d'une instance d'entité rattachée en utilisant la table parent:

var entityType = typeof(myEntity); 
var table = dataContext.GetTable<entityType>(); 
var modifiedMembers = table.GetModifiedMembers(myEntity); 

if (modifiedMembers.Any()) 
{ 
     ... changes were made 
} 
else 
{ 
     ... no changes were made 
} 

MAIS - vous devez le faire avant SubmitChanges(), bien sûr. J'utilise cette approche au lieu de GetChangeSet(), en raison de la meilleure fidélité de type, et du fait que vous pouvez facilement inspecter les modifications elles-mêmes.

1

aussi vous pouvez essayer cette classe d'aide et linq2sql:

public static class DataContextExtensions 
{ 
    /// <summary> 
    ///  Discard all pending changes of current DataContext. 
    ///  All un-submitted changes, including insert/delete/modify will lost. 
    /// </summary> 
    /// <param name="context"></param> 
    public static void DiscardPendingChanges(this DataContext context) 
    { 
     context.RefreshPendingChanges(RefreshMode.OverwriteCurrentValues); 
     ChangeSet changeSet = context.GetChangeSet(); 
     if (changeSet != null) 
     { 
      //Undo inserts 
      foreach (object objToInsert in changeSet.Inserts) 
      { 
       context.GetTable(objToInsert.GetType()).DeleteOnSubmit(objToInsert); 
      } 

      //Undo deletes 
      foreach (object objToDelete in changeSet.Deletes) 
      { 
       context.GetTable(objToDelete.GetType()).InsertOnSubmit(objToDelete); 
      } 

      //Undo updates 
      foreach (object objToUpdate in changeSet.Updates) 
      { 
       context.Refresh(RefreshMode.OverwriteCurrentValues, objToUpdate); 
      } 
     } 
    } 

    /// <summary> 
    ///  Refreshes all pending Delete/Update entity objects of current DataContext according to the specified mode. 
    ///  Nothing will do on Pending Insert entity objects. 
    /// </summary> 
    /// <param name="context"></param> 
    /// <param name="refreshMode">A value that specifies how optimistic concurrency conflicts are handled.</param> 
    public static void RefreshPendingChanges(this DataContext context, RefreshMode refreshMode) 
    { 
     ChangeSet changeSet = context.GetChangeSet(); 
     if (changeSet != null) 
     { 
      context.Refresh(refreshMode, changeSet.Deletes); 
      context.Refresh(refreshMode, changeSet.Updates); 
     } 
    } 
    /// <summary> 
    /// Get list of items of specific type that have been changed in a context.including their original and new values 
    /// </summary> 
    /// <typeparam name="TItem"></typeparam> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    public static List<ChangedItems<TItem>> GetChangedItems<TItem>(DataContext context) 
    { 
     // create a dictionary of type TItem for return to caller 
     List<ChangedItems<TItem>> changedItems = new List<ChangedItems<TItem>>(); 

     // use reflection to get changed items from data context 
     object services = context.GetType().BaseType.GetField("services", 
      BindingFlags.NonPublic | 
      BindingFlags.Instance | 
      BindingFlags.GetField).GetValue(context); 

     object tracker = services.GetType().GetField("tracker", 
      BindingFlags.NonPublic | 
      BindingFlags.Instance | 
      BindingFlags.GetField).GetValue(services); 
     System.Collections.IDictionary trackerItems = 
      (System.Collections.IDictionary)tracker.GetType().GetField("items", 
       BindingFlags.NonPublic | 
       BindingFlags.Instance | 
       BindingFlags.GetField).GetValue(tracker); 

     // iterate through each item in context, adding 
     // only those that are of type TItem to the changedItems dictionary 
     foreach (System.Collections.DictionaryEntry entry in trackerItems) 
     { 
      object original = entry.Value.GetType().GetField("original", 
       BindingFlags.NonPublic | 
       BindingFlags.Instance | 
       BindingFlags.GetField).GetValue(entry.Value); 

      if (entry.Key is TItem && original is TItem) 
      { 
       changedItems.Add(
        new ChangedItems<TItem>((TItem)entry.Key, (TItem)original) 
        ); 
      } 
     } 
     return changedItems; 
    } 

    /// <summary> 
    /// Returns a list consist a pair if original-current values of each property for the given type. 
    /// First KeyValue is current and second one is original. 
    /// </summary>/// <typeparam name="T"></typeparam> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    public static List<Dictionary<string, object>> GetObjectDiff<T>(this DataContext context) 
    { 
     List<Dictionary<string, object>> diff = new List<Dictionary<string, object>>(); 

     try 
     { 
      Debuging.Info("Try to GetObjectDiff"); 
      var changes = DataContextExtensions.GetChangedItems<T>(context); 

      foreach (ChangedItems<T> changedItem in changes) 
      { 
       PropertyInfo[] props = typeof(T).GetProperties(); 

       var dictCurrent = new Dictionary<string, object>(); 

       foreach (PropertyInfo prp in props) 
       { 
        object value = prp.GetValue(changedItem.Current, new object[] { }); 
        dictCurrent.Add(prp.Name, value); 
       } 

       var dictOrigin = new Dictionary<string, object>(); 

       foreach (PropertyInfo prp in props) 
       { 
        object value = prp.GetValue(changedItem.Original, new object[] { }); 
        dictOrigin.Add(prp.Name, value); 
       } 

       foreach (var item in dictCurrent) 
       { 
        var paired = dictOrigin.SingleOrDefault(a => a.Key == item.Key); 
        if (paired.Value != item.Value) 
        { 
         var first = new Dictionary<string, object>(); 
         first.Add(item.Key,item.Value); 
         diff.Add(first); 

         var second = new Dictionary<string, object>(); 
         second.Add(paired.Key, paired.Value); 
         diff.Add(second); 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Debuging.Error(ex, "DataContextExtensions.GetObjectDiff"); 
     } 
     return diff; 
    } 

    /// <summary> 
    /// Detect if there is any changed object in the context or not. 
    /// </summary> 
    public static bool HasChanges(this DataContext context) 
    { 
     ChangeSet changeSet = context.GetChangeSet(); 

     if (changeSet != null) 
     { 
      return changeSet.Inserts.Any() || changeSet.Deletes.Any() || changeSet.Updates.Any(); 
     } 

     return false; 
    } 

    public class ChangedItems<T> 
    { 
     public ChangedItems(T current, T original) 
     { 
      this.Current = current; 
      this.Original = original; 
     } 

     public T Current { get; set; } 
     public T Original { get; set; } 
    } 


} 
Questions connexes