有没有办法确定LINQ对象是否尚未插入数据库(新)或自上次更新(脏)后是否已更改?我计划将我的UI绑定到LINQ对象(使用WPF),并且需要它根据对象是否已经存在于数据库中而表现不同。
MyDataContext context = new MyDataContext();
MyObject obj;
if (new Random().NextDouble() > .5)
obj = new MyObject();
else
obj = context.MyObjects.First();
// How can I distinguish these two cases?
我能想到的唯一简单解决方案是将新记录的主键设置为负值(我的PK是一个标识字段,因此将在{{上设置为正整数) 1}})。这仅适用于检测新记录。它还需要身份PK,并需要控制创建新对象的代码。
有更好的方法吗?似乎LINQ必须在内部跟踪这些对象的状态,以便它可以知道在INSERT
上做什么。有没有办法访问“对象状态”?
澄清 显然我的初步问题令人困惑。我不是在寻找插入或更新记录的方法。我正在寻找一种方法,给定任何LINQ对象,以确定该对象是否未插入(新)或自上次更新(脏)后是否已更改。
答案 0 :(得分:14)
ChangeSet changes = context.GetChangeSet();
如果changes.Inserts.Contains(yourObject)则为new,将在调用SubmitChanges时插入
如果changes.Updates.Contains(yourObject),它已经在数据库中,并将在SubmitChanges()上更新
答案 1 :(得分:2)
我为LINQ创建的每个对象创建一个分部类(Data Objects)并让每个对象实现IDataObject接口
/// <summary>
/// This interface is used to implement IsNew in all LINQ objects so a Generic Save method
/// can be used.
/// </summary>
public interface IDataObject
{
#region Properties
#region IsNew
/// <summary>
/// Is this a new object
/// </summary>
bool IsNew
{
get;
}
#endregion
#endregion
}
#endregion
在每个数据对象中,如果已设置PrimaryKey,我实现IsNew属性以返回true:
/// <summary>
/// Is this a new object
/// </summary>
public bool IsNew
{
get
{
// initial value
bool isNew = (this.CustomerID > 0);
// return value
return isNew;
}
}
然后在我的DataContext中,我将ojbect转换为IDataObject,如果是new,我在调用SubmitChanges()之前调用InsertOnSubmit()。
这可能不是最简单的方法,但它允许一般保存所有对象。
每个表都需要几分钟才能实现接口,但它允许调用Generic Save()方法。
答案 2 :(得分:1)
DataContext对象在内部跟踪数据的更改,以便它可以优化调用SubmitChanges()时生成的SQL查询。
如果要将新对象插入数据库,而不是更新现有对象,则应执行以下操作:
MyDataContext context = new MyDataContext();
MyObject obj;
if (new Random().NextDouble() > .5)
{
obj = new MyObject();
context.MyObjects.InsertAllOnSubmit(obj);
}
else
obj = context.MyObjects.First();
现在,当您调用SubmitChanges()时,如果需要,它将生成INSERT和UPDATE。根据您在新对象上需要主键的速度,您可以立即提交它以提交对象,刷新更改跟踪并获取新的主键。
答案 3 :(得分:0)
有INotifyPropertyChanging和INotifyPropertyChanged接口,这些接口具有在插入时触发的特定方法,可以让您知道对象是否变脏。如果您使用SQLMetal,它会自动执行。如果你编写自己的实体类,你自己手动编写这些管道工作人员。但我不确定这种解决方案是否适合从可扩展性的角度来看。我没有测试过。它似乎可能有问题,因为它会在插入的机器上触发事件。
答案 4 :(得分:0)
问题How can I add an "IsDirty" property to a LINQ to SQL entity?有an answer ongle,如何使用PropertyChanged事件实现IsDirty属性。
限制:如果属性已更改,则显示IsDirty为true,然后撤消。