我在ASP.NET MVC 3应用程序中使用代码优先方法,并且模型中的所有整数主键(public int Id { get; set; }
)默认配置为具有自动递增的标识。如何禁用它并启用一种手动输入主键整数的方法?
实际情况是Id
整数具有特殊含义,因此我希望在创建时可以选择它们,然后再编辑。如果在创建时未给出整数,则自动递增,这将是理想的,否则使用指定的值。但可编辑的主要字段是我的主要需求。有没有办法在ASP.NET MVC 3中优雅地做到这一点?
答案 0 :(得分:51)
使用这些数据注释选项:
[System.ComponentModel.DataAnnotations.KeyAttribute()]
[System.ComponentModel.DataAnnotations.DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
答案 1 :(得分:27)
您可以使用FluentMapping:
modelBuilder.Entity<*entityname*>().Property(m => m.*fieldname*)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
答案 2 :(得分:3)
如果你想在EntityFramework Core 2.0中使用流畅的api,你可以写:
modelBuilder.Entity<*myEntity*>()
.Property(e => e.*myFieldname*)
.ValueGeneratedNever();
答案 3 :(得分:2)
我刚安装了最新的EntityFramework.dll 5.0.0版,我相信......
然而,由于有一个运行版本,我有一半时间感到困惑 v4.0.30319和版本4.4.0.0但是,我确信从网站上我 在我的搜索中提到了(它告诉我通过&#34; Package安装 Mangager控制台&#34;您可以通过VS中的菜单进入 &#34;工具|库包管理器|包管理器控制台&#34;并输入 &#34; PM&gt;&#34;提示&#34; Install-Package EntityFramework [可选:版本 数字或-Pre为最新的预发布(测试版)]&#34;)它是 5.0.0。
...,并且有一个属性&#34; System.CompnentModel.DataAnnotations.DatabaseGenerated(Computed,Identity或None)(以前的版本)或[...]。Schema.DatabaseGenerated(最新版本)&# 34;你可以用的。所以要么使用这个属性,要么使用如上所述的流畅的映射思想(由William Haack编辑(由Remo Gloor编辑)),如果不是代码优先(即改变生产),那么如上所述(由Adam Tuliper),你将需要写和执行一个关闭脚本以关闭标识插入。最重要的是,如果您不提供ID,则可以通过在代码中检索表上的MAX(ID)+ 1(并记住多用户环境中的并发问题)或触发器来模拟身份插入。或者,如果你想插入漏洞,就像表达式一样,你可以在触发器中执行此操作,也可以拦截插入的行并检查ID列是否已设置,如果是,则继续插入,否则, 首先设置值。插入漏洞的一种方法是使用这个技巧(我在一些我不记得的网站上看到,所以我在这里猜一点)你从一些大桌面有效地做一个反内连接您的表中的单列rownumbers以查找第一个可用的未使用的标识号(即查找不是目标表成员的第一个rownumber)。
在SQL Server 2005及更高版本中:
CREATE TRIGGER updInsYourTable_PlugHolesOnIDIfNull
ON YourTable
FOR update, insert AS
BEGIN
DECLARE @ID INT
SELECT @ID = ID FROM INSERTED
IF @ID IS NULL
BEGIN
;WITH CTE_StagedNumbers AS
(
SELECT ROW_NUMBER() OVER (ORDER BY o.object_id) AS NextFreeIdentity
FROM ( SELECT object_id FROM sys.objects
-- UNION ALL
-- SELECT object_id FROM sys.objects
/* NB: Here if sys.objects is not larger enough say on a small schema
configured database then use a different table otherwise you can
always union all on the same table as many times as you want to
double, triple etc. its size. */
) o
)
UPDATE YourTable
SET ID = (
SELECT TOP 1 NextFreeIdentity
FROM CTE_StagedNumbers
WHERE NextFreeIdentity NOT IN (SELECT ID FROM YourTable)
)
WHERE ID IS NULL
END
END
GO
注意,CTE_StagedNumbers不是必需的,它只是用于强调,主要技巧不一定是设置行号,但是,如果你要设置一个永久的临时表(比如说StagedNumbers)一个没有自动标识的单个整数列(比如NextFreeIdentity INT NOT NULL PRIMARY KEY),(除了NB:你的ID列的YourTable定义必须接受null,因为我们使用的是后触发器)预先填充了连续的正数 - 使用上述技术从1开始的整数值,然后完全删除CTE并用StagedNumbers替换最终选择中的CTE_StagedNumbers,那么这将是最有效的。
答案 4 :(得分:1)
如果这是数据库中的标识字段,则无法进行。那么你可以通过在数据库端设置身份插入,但通过良好的实践,除非批量插入记录,否则你不应该这样做。如果您不希望将此作为标识,请在该列的DB中将identity选项设置为false。
答案 5 :(得分:1)
使用属性:
public class MessageSubject
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string Title { get; set; }
public string Comment { get; set; }
public bool BuildIn { get; set; }
}
答案 6 :(得分:0)
从外键表中删除“必需”属性对我来说是成功的。