代码之家  ›  专栏  ›  技术社区  ›  Jeremy Cantrell

如何判断submitChanges()是否会实际更改linq to sql中特定实体的任何内容

  •  4
  • Jeremy Cantrell  · 技术社区  · 16 年前

    我正在尝试确定是否对特定实体对象进行了任何更改。本质上,我想知道SubmitChanges()是否真的会改变任何东西。我希望能够在调用SubmitChanges()之后确定这一点,但这并不重要。

    有人知道我会怎么做吗?

    4 回复  |  直到 9 年前
        1
  •  6
  •   joshperry    16 年前

    看看 GetChangeset 对您的DataContext执行函数。

        2
  •  2
  •   Sam    16 年前

    可以使用父表直接访问附加实体实例的更改:

    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(),因为它具有更好的类型保真度,而且您可以轻松地检查更改本身。

        3
  •  1
  •   Jeremy Cantrell    16 年前

    这就是我想到的:

    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
    
        4
  •  1
  •   Arash Masir    9 年前

    此外,您还可以尝试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; }
        }
    
    
    }