我正在尝试确定是否对特定实体对象进行了任何更改。基本上,我想知道SubmitChanges()是否会实际改变任何东西。我希望能够在调用SubmitChanges()之后确定这一点,但这并不重要。
任何人都知道我会这样做吗?
答案 0 :(得分:6)
查看DataContext上的GetChangeset函数。
答案 1 :(得分: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(),因为更好的类型保真度,以及您可以轻松地自己检查更改的事实。
答案 2 :(得分: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
答案 3 :(得分:1)
你也可以尝试使用linq2sql的Helper类:
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; }
}
}