实体框架在* lookup *表上抛出SqlDate异常

时间:2009-12-25 09:32:50

标签: asp.net asp.net-mvc entity-framework

我正在使用asp.net mvc实体框架,但我不认为mvc在这里发挥了重要作用。

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

如果我对Territory进行硬编码,并且只从View中获取客户数据,我没有任何问题:

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很好地分配给Customer对象的相应成员。坏消息是Territory.LastUpdated值设置为1/01/0001。显然,并不关心这个价值 - 但它看起来像EF关心。当我调用SaveChanges时,我收到以下错误:

  

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

看起来EF正在尝试从数据库中检索值,然后将其与EF值进行比较......或者可能是其他东西 - 但最重要的是我无法弄清楚如何防止它试图成为太聪明了。

现在,我将DropDown 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 个答案:

答案 0 :(得分:1)

Territory.LastUpdated正在设置为默认值,因为EF保存整行/更改后的内容会出现异常。

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

答案 1 :(得分:0)

我假设你使用的是EF 1.0,它不擅长直接外键maping。

从视图到操作发布的区域未绑定到Datacontext,因此当您保存客户对象时 - EF也会保存附加的区域对象。

您必须首先从db获取Territory对象,然后将其分配给customer。

而且你的解决方案非常好,因为EF 1.0没有其他功能) - :