如何确保Linq to Sql不会覆盖或违反不可空的数据库默认值?

时间:2008-10-14 15:44:37

标签: c# sql linq sql-server-2005 linq-to-sql

我有一个带有这些字段的表的SQL Server数据库:

  1. bit,其默认值为NOT NULL
  2. smalldatetime,其默认值为gettime()NOT NULL
  3. int没有默认值,IDENTITYNOT NULL
  4. 当我为此表生成Linq to SQL时,会发生以下情况:

    1. bit没有得到特殊处理。
    2. smalldatetime没有得到特殊处理。
    3. int标记为IsDbGenerated
    4. 这意味着当我使用Linq to SQL进行插入时,将发生以下情况:

      1. bit将被发送为0,覆盖默认值。 从右吗
      2. smalldatetime将作为未初始化的System.DateTime发送,在SQL Server中产生错误,因为它不符合SQL Server smalldatetime范围。 从右吗
      3. IsDbGenerated int将不会被发送; DB将生成一个Linq to SQL将读回的值。
      4. 我需要做些哪些更改才能使此方案有效?

        总结一下:我希望不可为空的字段具有DB分配的默认值,但我不希望它们IsDbGenerated,如果这意味着我在使用Linq to SQL进行更新或插入时无法为它们提供值。如果这意味着我必须手动修改Linq生成的代码到SQL,我也不希望它们IsDbGenerated

        编辑:答案似乎是当前Linq to SQL的限制。

4 个答案:

答案 0 :(得分:5)

Linq-To-Sql生成的类不会选择默认值Constriants。

也许在未来,但问题是约束并不总是简单的值,它们也可以是像GetDate()这样的标量函数,所以linq必须知道如何翻译它们。简而言之,它甚至都没有尝试过。它也是一种特定于数据库的东西。

  • 您可以编写代码生成器来创建实体分部类,您可以在其中提取默认值constriant。
  • 或者,您的业务层代码可以从xml文件中设置构造函数中的默认值,您需要做的就是使xml文件保持最新。
  • 您可以通过在提交对数据库的更改之前检查ChangeSet来模拟SQL并添加默认值,而不是在构造函数中完成工作。

您遇到的问题详见CodeProject - Setting Default Values for LINQ Bound Data

答案 1 :(得分:3)

我遇到了同样的问题,bzlm,得出了同样的结论。使用DB分配的默认值使用Linq To Sql获取不可为空的字段是没有好办法的。

我已经解决的问题是添加一个非常类似于Robert Paulson在CodeProject上链接的SetDefaults()方法,并在我的表实体基类的默认构造函数中调用它。它适用于我,因为95%的时间,我设置0,空字符串,或getdate()。

答案 2 :(得分:2)

  
    

这意味着当我使用Linq to SQL进行插入时,以下内容将会如此     发生:

  
     
      
  1. 该位将作为0发送,覆盖默认值。对? - 正确
  2.   
  3. smalldatetime将作为未初始化的System.DateTime发送,   从那时起在SQL Server中产生错误   它不符合SQL Server   smalldatetime范围。对? - 发送的内容是DateTime.MinValue
  4.   
  5. 不会发送IsDbGenerated int; DB将生成一个值   然后Linq to SQL将回读。 - 如果设置了DB生成,那么数据库将创建该值,否则Linq希望用户设置该值。
  6.   

如果您没有使用自动属性,最好的办法是在对象的构造函数或私有字段中设置它们。

答案 3 :(得分:0)

您可以为datacontext(部分类)创建另一个文件,然后使用InsertYOURENTITY和UpdateYOURENTITY部分方法检查属性并分配正确的值。 在代码之后调用ExecuteDynamicInsert或ExecuteDynamicUpdate并进行设置。