我有一个web应用程序(MVC 5,EntityFramework 6)。它通过DbContext连接到SQL数据库。我遇到了一个问题,添加一个新的实体对象会在实体集中(但不是DB)创建一个重复的条目,我不知道如何阻止这种情况的发生。
控制器,其方法通过ajax请求调用:
public class CustomerController : Controller
{
MyDBEntities db = new MyDBEntities(); //DbContext
public ActionResult SaveStuff(string customerId, string stuff)
{
Customer customer = db.Single(c => c.ID.Equals(customerId));
Stuff stuff = new Stuff(stuff, customer);
db.Stuffs.Add(stuff);
db.SaveChanges();
return PartialView("MyControl", customer);
}
}
Customer和Stuff之间存在一对多关联,Customer中有一个"Stuff"导航属性。
Stuff包括int、string和DateTime的字段。
controller方法返回一个PartialView,JavaScript使用它来刷新控件的内容。
"MyControl"控件执行以下操作:
var stuffs = Model.Stuffs.OrderByDescending(...);
在这种情况下呈现控件时,Model.Stuffs
包含一个重复条目。有一个名称为Stuff
的条目(可能是在控制方法中创建的新对象),还有一个名为System.Data.Entity.DynamicProxies.Stuff_<uuid>
的条目,它是完全相同的数据(我想是从DB中读取的)。
这只是当我向同一个web请求中的实体集写入并从中读取时的问题。其他/将来引起读取的web请求也可以。我如何才能使其正确工作?
之所以会发生这种情况,是因为DateTime对象在写入SQL数据库时会丢失精度(请参阅:SQL Server DateTime与.NET DateTime)。从数据库中读取时,它具有不同的值,因此不会覆盖数据库中本地仍然存在的现有"stuff"对象。东西。
一个简单的解决方案是将Stuff的DateTime的setter更改为private,并添加您自己的伪setter函数,该函数内置了舍入:
public void SetTimestamp(DateTime timestamp)
{
//Precision in SQL is lower than in .NET, so just round to tenth seconds
this.Updated = timestamp.AddTicks(- (timestamp.Ticks % (TimeSpan.TicksPerSecond / 10)));
}
在SQL数据库(Server 2008+)中使用DateTime2也是一个选项,如果您需要保持该精度级别的话。