代码之家  ›  专栏  ›  技术社区  ›  Felix

实体框架在*lookup*表上引发sqldate异常

  •  0
  • Felix  · 技术社区  · 15 年前

    我正在将实体框架与ASP.NET MVC结合使用,但我认为MVC在这里不起很大作用。

    我有一个对象客户和一个查找表(有几个,它们的行为都相同;为了简单起见,我将选择区域)。Customer和Territory都有LastUpdated字段(在代码中手动设置的日期时间)。

    如果我对区域进行硬编码,并且只从视图中获取客户数据,那么我没有任何问题:

    public ActionResult CreateCustomer([Bind(Exclude = "CustId")] Customer cm) {
        cm.Territory = (from t in repo.Territory where t.ID == 2 select t).First();
        repo.AddToCustomer(cm);
        repo.SaveChanges();
    }
    

    如我所说,没问题。但是,如果在视图中使用具有匹配ID(territory.id)的下拉列表,则会出现问题。我在控制器中有以下行:

    ViewData["territory"] = new SelectList(repo.Territory, "ID", "Name", 1);
    

    以及视图中的对应行:

    Territory: <%= Html.DropDownList("Territory.ID", (IEnumerable<SelectListItem>)ViewData["territory"])%>
    

    我会得到好消息和坏消息:好消息是我会很好地将区域ID分配给客户对象的适当成员。坏消息是territory.lastupdated值设置为1/01/0001。很明显, 不在乎这个价值-但看起来英孚在乎。当我调用savechanges时,得到以下错误:

    sqldetime溢出。必须在1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间

    似乎ef正在尝试从数据库中检索值,然后将其与ef值进行比较…或者其他的事情——但底线是我不知道如何阻止它变得如此聪明。

    现在,我将下拉ID命名为不同的内容(“terid”而不是“territory.id”),并使用formcollection:

    int terID = Int32.Parse(formData["terID"]);
    cm.Territory = (from d in repo.Territory
         where d.ID == terID select d).First();
    

    这是可行的(这让我对我的分析感到满意),但这不是最好的方法。 我也不能相信没有人碰到这样的问题-但我找不到任何相关的…我能找到的最好的是 link text 但这更像是一个没有太多细节的暗示

    我试图从代码中删掉所有不相关的东西——所以如果有一些拼写错误,它们就在文章中;不一定在代码本身中! 谢谢

    2 回复  |  直到 15 年前
        1
  •  0
  •   Alexander Taran    15 年前

    我假设您使用的是EF1.0,它不擅长直接外键映射。

    从视图发布到操作的区域不绑定到DataContext,因此在保存客户对象时-ef也会保存附加的区域对象。

    您必须先从DB获取Territory对象,然后将其分配给客户。

    你的解决方案是完美的,因为没有其他的ef 1.0)-:

        2
  •  1
  •   Shiraz Bhaiji    15 年前

    territory.lastupdated将被设置为默认值,因为ef保存整行/更改的内容会得到一个异常。

    解决此问题的简单方法是将其设置为datetime。现在保存之前。