我正在通过 EntityFramework 4 (EF) 将一个对象插入到 SQL Server 数据库中。接收表上有一列 (
CreatedDate
),其默认值设置为 getdate()
。因此,我不会将其提供给 EF,假设 SQL Server 将其值默认为 getdate()
。
然而这并没有发生;相反,EF 返回验证错误 n
SaveChanges()
。
您知道发生这种情况的原因吗?请告诉我。
非常感谢。
如果您不想编辑该值(例如创建日期),您可以使用:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual DateTime CreatedDate { get; set; }
这将告诉实体框架该值由数据库控制,但仍会获取该值。
请注意,您无法更改该值,因此如果您只想要一个初始值,这不是一个解决方案。
如果您只想要一个默认值但仍允许编辑它,或者您使用的是 Entity Framework 5 及更低版本,则必须在代码中设置默认值。
更多关于此的讨论:
只需将
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
属性应用于实体对象定义中的列字段。
例如:
public class SomeTable
{
...
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime CreatedDate { get; set; }
...
}
这告诉实体框架您的列的初始值是由数据库提供的。插入行后,该值将从数据库自动更新。
此问题的正确答案是告诉实体框架该列已计算。
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual DateTime CreatedDate { get; set; }
DatabaseGeneratedOption.Computed
表示它是由数据库设置的,不能由实体框架更改。 DatabaseGeneratedOption.Identity
表示该列是 IDENTITY 列,仅用于自动递增数字主键。
**请注意,DatabaseGenerateOption 枚举的文档没有提及任何有关 IDENTITY 列的内容(部分原因是这是 SqlServer 特定的实现细节)。相反,它将 Identity 选项定义为“插入行时数据库生成一个值”。我实际上正在寻找一种方法,允许在创建记录时使用 DEFAULT 约束设置 ModDate,但允许在更新记录时从实体框架对其进行修改。因此,根据描述,我认为我可能已经找到了解决方案,但尝试修改带有
DatabaseGeneratedOption.Identity
标记的记录的 ModDate 会引发异常。所以没有运气。
尝试使用这个。
public virtual DateTime CreatedDate { get; set; } = new Datetime();
您也可以在实体数据模型的 GUI 中将
StoreGeneratedPattern
设置为“已计算”(如 Malcolm 建议)。
在 Visual Studio 中打开您的
.edmx
文件
打开字段的属性(单击字段 -> 点击 F4 或 right-click->properties
)
在 StoreGeneratedPattern
中将 properties window
设置为 Computed,如下所示:
为了开始工作,我声明了一个新变量并将该变量设置为当前时间。然后,在插入数据时,我将变量引用到列:
var db = new YourTableEntities();
var dateNow = DateTime.Now;
db.YourTableEntities.Add(new YourTableEntities()
{
ColumnAInTable = someAVariable,
ColumnBInTable = someBVariable,
ColumnThatShouldDefaultToGetDate = dateNow
});
希望这有帮助!