实体框架为NOT NULL列生成值,其默认值在db中定义

时间:2011-03-17 15:27:52

标签: c# entity-framework-4

您好我有一张桌子客户。表中的一列是DateCreated。此列为NOT NULL,但在db。

中为此列定义了默认值

当我使用代码中的EF4添加新Customer时。

var customer = new Customer();
customer.CustomerName = "Hello";                
customer.Email = "hello@ello.com";
// Watch out commented out.
//customer.DateCreated = DateTime.Now;
context.AddToCustomers(customer);
context.SaveChanges();

以上代码生成以下查询。

exec sp_executesql N'insert [dbo].[Customers]([CustomerName], 
[Email], [Phone], [DateCreated], [DateUpdated])
values (@0, @1, null, @2, null)
select [CustomerId]
from [dbo].[Customers]
where @@ROWCOUNT > 0 and [CustomerId] = scope_identity()
',N'@0 varchar(100),@1 varchar(100),@2 datetime2(7)
',@0='Hello',@1='hello@ello.com',@2='0001-01-01 00:00:00'

并抛出错误

The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.

您能否告诉我在db级别具有默认值的NOT NULL列如何不具有EF生成的值?

DB:

DateCreated DATETIME NOT NULL

EF中的DateCreated属性:

  • Nullable: False
  • Getter / Setter: public
  • 输入:日期时间
  • DefaultValue:

感谢。

5 个答案:

答案 0 :(得分:7)

根据我对EF(最小)的了解,它不会从架构中获取默认值。您插入行和列的事实被标记为NOT NULL,这意味着EF认为它应该为该列插入一个恰好具有DateTime.MinValue值的值。

您可能需要在实体构造函数中强制使用自己的值,或者创建一些工厂方法。

EF中的表设计器的属性页上是否有任何内容可以指定默认值?

答案 1 :(得分:3)

NOT NULL列表示该属性不可为空,并且它必须在您的实体中具有值。如果未在DateTime等值类型中指定值,则将保留默认值。 DateTime的默认值为DateTime.MinValue

据我所知,EF不支持您可以使用NOT NULL列并且不从您的应用程序发送任何值的情况。唯一的例外是当您将属性的StoreGeneratedPattern设置为IdentityComputed时,但在这种情况下,您将无法在应用程序中设置该值。

因此,您可以在应用程序或数据库中设置值。不在两者中。

答案 2 :(得分:2)

您必须向ORM说,该属性是由数据库生成的。对于上一个示例中Customer Class中的示例,以下代码应该可以使用。

public class Customer{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]//The database generates a value when a row is inserted. 
    public int CustomerId { get; set; }

    public string CustomerName { get; set; }

    public string Email { get; set; }

    public string Phone { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)] //The database generates a value when a row is inserted or updated.
    public DateTime DateCreated { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.IComputed)]//The database generates a value when a row is inserted or updated.
    public DateTime DateUpdated { get; set; }

}

不要忘记添加

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 

主键,由于我不知道的原因,当你在Model Class中至少使用一次DatabaseGeneratedAttribute时,你必须指定生成的选项方法。当我使用它们时,我有一个错误,因为ORM试图在查询语句中插入密钥而不是让数据库生成它们。

有三个数据库生成选项

  • 已计算:插入或更新行时,数据库会生成一个值。
  • 标识:插入行时,数据库会生成一个值。
  • :数据库不会生成值。

您可以在Database Generated Options

找到相关文档

答案 3 :(得分:0)

DateCreated列可能是smalldatetime,需要是datetime类型吗?尝试在Visual Studio或Management Studio中更改列类型。

答案 4 :(得分:0)

  1. 设置DateCreated允许空值
  2. 为INSERT添加触发器

    CREATE TRIGGER [dbo]。[ItemCreated]

    ON [dbo]。[myTable]

    插入后

    AS

    更新[dbo]。[myTable]

    SET [DateCreated] = GETDATE()

    WHERE [ID] IN(SELECT DISTINCT [ID] FROM [Inserted])和[DateCreated]为NULL