2008-12-11 41 views

回答

1

這是我想出了:

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

查看DataContext上的GetChangeset函數。

+0

但是留意鏈接MSDN文章 – 2008-12-11 16:13:43

2

可以使用父表直接訪問一個連接實體實例的變化:

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 
} 

但是 - 你之前做SubmitChanges(),當然。由於更好的類型保真度以及可以輕鬆檢查更改本身的事實,我使用此方法而不是GetChangeSet()。

1

也可以試試這個助手類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; } 
    } 


} 
相關問題