EF 6,向DbContext添加实体会创建重复实体

时间:2014-11-06 03:44:35

标签: entity-framework asp.net-mvc-5 dbcontext ef-database-first

我有一个Web应用程序(MVC 5,EntityFramework 6)。它通过DbContext连接到SQL数据库。我有一个问题,即添加新的实体对象会在实体集中创建重复的条目(但不会在数据库中创建),而且我不确定如何阻止这种情况发生。

Controller,其方法通过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之间存在1对多的关联,并且有一个" Stuffs"客户中的导航属性。

Stuff包含 int string DateTime 的字段。

控制器方法返回一个PartialView,JavaScript用它来刷新控件的内容。

" MyControl"控制这样做:

var stuffs = Model.Stuffs.OrderByDescending(...);

在这种情况下呈现控件时,Model.Stuffs包含重复的条目。这里有一个名为Stuff的条目(可能是在控制方法中创建的新对象),以及名称为System.Data.Entity.DynamicProxies.Stuff_<uuid>的条目,它是完全相同的数据(我想从DB读取。

当我在同一个网页请求中写入并读取实体集时,这只是一个问题。导致读取的其他/未来Web请求很好。我怎样才能正常工作?

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为DateTime对象在写入SQL数据库时会丢失精度(请参阅:SQL Server DateTime vs .NET DateTime)。从DB读回时,它具有不同的值,因此不会覆盖db.Stuffs中本地仍然存在的现有“stuff”对象。

一个简单的解决方案是将DateTime的Stuff 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也是一种选择。