如何确保Linq to Sql不会覆盖或违反不可空的数据库默认值?
我有一个带有这些字段的表的SQL Server数据库:
- 一个默认值为1的位,
NOT NULL
。 - 具有默认值
gettime()
smalldatetime
,NOT NULL
。 - 没有默认值的
int
,IDENTITY
,NOT NULL
。
当我为此表生成Linq to SQL时,会发生以下情况:
- 该
bit
没有特殊处理。 -
smalldatetime
没有给予特殊处理。 -
int
标记为IsDbGenerated
。
这意味着当我使用Linq to SQL进行插入时,将发生以下情况:
- 该
bit
将作为0发送,覆盖默认值。 对? -
smalldatetime
将作为未初始化的System.DateTime
发送,在SQL Server中产生错误,因为它不符合SQL Server smalldatetime范围。 对? - 不会发送
IsDbGenerated
int
; DB将生成一个Linq to SQL将读回的值。
要使此方案有效,我需要做哪些更改?
总结一下:我想要使用DB分配的默认值的非可空字段,但我不希望它们是IsDbGenerated
如果它意味着我在使用Linq to SQL进行更新或插入时无法为它们提供值。 如果这意味着我必须手动修改Linq生成的代码到SQL,我也不希望它们是IsDbGenerated
。
编辑:答案似乎是这是当前Linq to SQL的限制。
Linq-To-Sql生成的类不会获取默认值Constriants。
也许在将来,但问题是约束并不总是简单的值,它们也可以是像GetDate()
这样的标量函数,所以linq必须知道如何翻译它们。 简而言之,它甚至都没有尝试过。 它也是一种非常特定于数据库的东西。
- 您可以编写代码生成器来创建实体分部类,您可以在其中提取默认值constriant。
- 或者,您的业务层代码可以从xml文件中设置构造函数中的默认值,您需要做的就是使xml文件保持最新。
- 您可以通过在提交对数据库的更改之前检查ChangeSet来模拟SQL并添加默认值,而不是在构造函数中执行工作。
您在CodeProject中详细描述了您遇到的问题- 为LINQ绑定数据设置默认值
我遇到了同样的问题,bzlm,得出了同样的结论。 使用与Linq To Sql一起使用DB分配的默认值的非可空字段是没有好办法的。
我已经解决的工作是添加一个非常类似于Robert Paulson在CodeProject上链接的SetDefaults()方法,并在我的表实体基类的默认构造函数中调用它。 它适用于我,因为95%的时间,我设置0,空字符串,或getdate()。
这意味着当我使用Linq to SQL进行插入时,将发生以下情况:
- 该位将作为0发送,覆盖默认值。 对? – 正确
- smalldatetime将作为未初始化的System.DateTime发送,在SQL Server中产生错误,因为它不符合SQL Server smalldatetime范围。 对? – 发送的是DateTime.MinValue
- 不会发送IsDbGenerated int; DB将生成一个Linq to SQL将读回的值。 – 如果设置了DB生成,则数据库将创建该值,否则Linq希望用户设置该值。
如果您没有使用自动属性,最好的办法是将它们设置在对象的构造函数中,或者设置在私有字段上。
您可以为datacontext(部分类)创建另一个文件,然后使用InsertYOURENTITY和UpdateYOURENTITY部分方法检查属性并分配正确的值。 在代码之后调用ExecuteDynamicInsert或ExecuteDynamicUpdate并进行设置。