最简单的办法:
所有列
你必须禁用并发检查(UpdateCheck.Never)(你可以转移双击它,在设计师,或者如果使用T4模板修改模板)。或者,您必须复制下面示例中的每个字段(可以生成一个模板方法来执行此操作)。
在任何情况下:
MyDataContext db = new MyDataContext();
MyDataContext db2 = new MyDataContext();
Car betsy = db.Cars.First(c => c.Name == "Betsy");
Car betsy2 = new Car();
betsy2.Id= betsy.Id;
db2.Cars.Attach(betsy2);
/* Could be GetName() or whatever, but allows same */
betsy2.UpdatedBy = betsy.UpdatedBy;
betsy2.OtherField = "TestTestTest";
db2.SubmitChanges();
一些其他的 “解决方案” 下面。不幸的是,所有这些都涉及到双重更新/无论如何,并且如果您正在进行删除,实际上并不奏效。当你正在审计的时候,你可能会备份到另一个表,你需要在你的触发器中打补丁,用'|'更新最后的审计记录。当你得到你的第二个非'|'或者什么东西(如果它总是在一个交易中,也许不是世界末日)。尽管如此,这并非理想。
凌乱的解决方案:
MyDataContext db = new MyDataContext();
Car car = db.Cars.First(c => c.Id == 1);
car.Name = "Betsy";
car.UpdatedBy = String.Format("{0}|{1}", car.UpdatedBy, DateTime.Ticks);
db.SubmitChanges();
car.UpdatedBy = car.UpdatedBy.Substring(0, car.UpdatedBy.LastIndexOf('|'));
db.SubmitChanges();
稍微好一点的解决办法:
public partial class MyDataContext : DataContext
{
public override void SubmitChanges(ConflictMode failureMode)
{
ChangeSet cs = base.GetChangeSet();
foreach (object e in cs.Updates.Union(cs.Inserts))
{
PropertyInfo updatedBy = e.GetType()
.GetProperties()
.FirstOrDefault(p => p.Name == "UpdatedBy");
if (updatedBy == null)
{
base.SubmitChanges(failureMode);
return;
}
string updatedByValue = updatedBy.GetValue(e, null);
string tempValue = String.Format("{0}|{1}", updatedByValue, DateTime.Ticks;
updatedBy.SetValue(e, tempValue);
base.SubmitChanges(failureMode);
updatedBy.SetValue(e, tempValue.Substring(0, tempValue.LastIndexOf('|')));
base.SubmitChanges(failureMode);
}
}
}
我发现(如果你使用T4模板的LINQ to SQL这种类型的最佳解决方案这更简单):
要么为部分类文件实现每个审计实体类型的公共接口,要么修改模板以便审计实体实现一个公共接口,例如:
public interface IAuditable
{
string UpdatedBy { get; set; }
}
然后修改您的SubmitChanges如下:
public partial class MyDataContext : DataContext
{
public override void SubmitChanges(ConflictMode failureMode)
{
ChangeSet cs = base.GetChangeSet();
foreach (object e in cs.Updates.Union(cs.Inserts))
{
if (typeof(IAuditable).IsAssignableFrom(e))
{
string tempValue = String.Format("{0}|{1}", ((IAuditable)e).UpdatedBy, DateTime.Ticks);
((IAuditable)e).UpdatedBy = tempValue;
base.SubmitChanges(failureMode);
((IAuditable)e).UpdatedBy = tempValue.Substring(0, tempValue.LastIndexOf('|'));
base.SubmitChanges(failureMode);
}
}
}
}
你可能想看看[这个问题](http://stackoverflow.com/questions/1560513/can-you-convince -a-datacontext-to-treat-a-column-as-always-dirty) – 2010-11-17 04:45:50
谢谢,不能完全得到正确的措词,但它是*确切*相同的问题。作为参考,我可以通过如果我使用两个数据上下文,或者如果我做两个更新(也许第二个追逐审计表并修改最新的记录..),但我无法找到使用一个数据上下文的方法,因为您无法将同一个id的实例附加到上下文中。反思可能就是这样。 – 2010-11-17 05:17:58
试图自我封闭,因为它是你的问题Marc的重复。你可以发表你的评论作为答案,以便我可以接受它吗?目前看来是最好的解决方案。 – 2010-11-23 00:20:37