这有点复杂,拜托,我知道反对自然PK的所有论据,所以我们不需要讨论。
使用VS2012 / MVC4 / C#/ CodeFirst
因此,PK基于日期和相应的数字。因此,今天创建的几行将是这样的:
20131019 1
20131019 2
明天创造了一个人:
20131020 1
这必须使用C#或触发器等自动生成。用户不会输入此内容。我确实想出了一个解决方案,但是我遇到了问题,而且我有点卡住,因此问题就出现了。
所以,我有一个模特:
public class MainOne
{
//[Key]
//public int ID { get; set; }
[Key][Column(Order=1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string DocketDate { get; set; }
[Key][Column(Order=2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string DocketNumber { get; set; }
[StringLength(3, ErrorMessage = "Corp Code must be three letters")]
public string CorpCode { get; set; }
[StringLength(4, ErrorMessage = "Corp Code must be four letters")]
public string DocketStatus { get; set; }
}
完成模型后,我使用VS2012脚手架创建了一个新的控制器和视图。
然后,我正在做的是调试创建数据库,然后在Code First创建数据库之后添加以下而不是触发器[我不知道这是否是正确的程序]:
CREATE TRIGGER AutoIncrement_Trigger ON [dbo].[MainOnes]
instead OF INSERT AS
BEGIN
DECLARE @number INT
SELECT @number=COUNT(*) FROM [dbo].[MainOnes] WHERE [DocketDate] = CONVERT(DATE, GETDATE())
INSERT INTO [dbo].[MainOnes] (DocketDate,DocketNumber,CorpCode,DocketStatus) SELECT (CONVERT(DATE, GETDATE
())),(@number+1),inserted.CorpCode,inserted.DocketStatus FROM inserted
END
当我尝试创建记录时,这就是我得到的错误:
已成功提交对数据库的更改,但更新对象上下文时发生错误。 ObjectContext可能处于不一致状态。内部异常消息:无法更改对象状态。此异常可能是由于一个或多个主键属性设置为null。未添加的对象不能具有空主键值。有关详细信息,请参阅内部异常。
现在,对我来说有趣的是,在我停止调试并重新开始之后,一切都很完美。触发器完全触发,因此复合PK是唯一且完美的,其他列中的数据完好无损。
我的猜测是,EF很容易被这样一个事实搞糊涂,因为在给出插入命令后,PK似乎没有任何价值。此外,似乎支持这一理论,当我尝试编辑行时,在调试中,我收到以下错误:
传递的主键值的数量必须与实体上定义的主键值的数量匹配。
如果我尝试拉出“详细信息”或“删除”功能,则会出现相同的错误。
关于如何解决此问题的任何解决方案或想法?我对任何事情都很开放,甚至创建一个隐藏的int PK。但这似乎是多余的。
编辑21OCT13
[HttpPost]
public ActionResult Create(MainOne mainone)
{
if (ModelState.IsValid)
{
var countId = db.MainOnes.Count(d => d.DocketDate == mainone.DocketNumber); //assuming that the date field already has a value
mainone.DocketNumber = countId + 1; //Cannot implicitly convert type int to string
db.MainOnes.Add(mainone);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(mainone);
}
编辑21OCT2013最终代码解决方案 对于像我这样的人,他们一直在寻找清晰完整的解决方案。
if (ModelState.IsValid)
{
String udate = DateTime.UtcNow.ToString("yyyy-MM-dd");
mainone.DocketDate = udate;
var ddate = db.MainOnes.Count(d => d.DocketDate == mainone.DocketDate); //assuming that the date field already has a value
mainone.DocketNumber = ddate + 1;
db.MainOnes.Add(mainone);
db.SaveChanges();
return RedirectToAction("Index");
}
答案 0 :(得分:1)
hy你不是通过代码管理而不是使用触发器吗?
var countId = context.MainOne.Count(d => d.DocketDate == newItem.DocketNumber); //assuming that the date field already has a value
newItem.DocketNumber = CountId + 1;
Context.MainOne.Add(newItem);
context.SaveChanges();
这可以解决你的问题。