实体框架为 NOT NULL 列生成值,该列在数据库中定义了默认值

发布于 2024-10-22 20:24:55 字数 1569 浏览 1 评论 0原文

嗨,我有一张桌子顾客。表中的一列是DateCreated。此列为 NOT NULL,但在 db.xml 中为此列定义了默认值。

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

var customer = new Customer();
customer.CustomerName = "Hello";                
customer.Email = "[email protected]";
// 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='[email protected]',@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.

您能否告诉我在数据库级别具有默认值的 NOT NULL 列不应具有 EF 生成的值?

DB:

DateCreated DATETIME NOT NULL

EF 中的 DateCreated 属性:

  • 可空: False
  • Getter/Setter: public
  • 类型: DateTime
  • DefaultValue:

谢谢。

Hi I have a table Customer. One of the columns in table is DateCreated. This column is NOT NULL but default values is defined for this column in db.

When I add new Customer using EF4 from my code.

var customer = new Customer();
customer.CustomerName = "Hello";                
customer.Email = "[email protected]";
// Watch out commented out.
//customer.DateCreated = DateTime.Now;
context.AddToCustomers(customer);
context.SaveChanges();

Above code generates following query.

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='[email protected]',@2='0001-01-01 00:00:00'

And throws following error

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

Can you please tell me how NOT NULL columns which has default values at db level should not have values generated by EF?

DB:

DateCreated DATETIME NOT NULL

DateCreated Properties in EF:

  • Nullable: False
  • Getter/Setter: public
  • Type: DateTime
  • DefaultValue: None

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

云归处 2024-10-29 20:24:55

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

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

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

From my knowledge of EF (which is minimal), it does not grab the default value from the schema. The fact that you are inserting the row and the column is marked as NOT NULL, means EF thinks it should be inserting a value for that column which happens to have the value of DateTime.MinValue.

You may need to force your own values in the entities constructor or create some factory methods.

Is there anything on the property pages of the table designer in EF that lets you specify a default value?

为人所爱 2024-10-29 20:24:55

你必须对ORM说该属性是由数据库生成的。对于上一个示例中的 Customer 类中的示例,以下代码应该可以工作。

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)] 

主键,由于我不知道的原因,当您在模型类中至少使用一次DatabaseGenerateAttribute的注释时,您必须指定生成的选项方法。当我使用它们时,我遇到错误,因为 ORM 试图在查询语句中插入键,而不是让数据库生成它们。

共有三个数据库生成选项

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

您可以在此处找到文档 数据库生成选项

You have to said to the ORM that the property is generated by the database. For the example in the Customer Class in the previous example, the following code should work.

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; }

}

Don't forget to add the

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 

to the primary key, for a reason that i not know, when you use the annotation of DatabaseGeneratedAttribute at least once in the Model Class, you have to specify the the generated option method. When i use them, i have an error because the ORM was trying to insert the key in the query statement instead of let the database to generate them.

There are three Database Generated Options

  • Computed : The database generates a value when a row is inserted or updated.
  • Identity : The database generates a value when a row is inserted.
  • None : The database does not generate values.

You can find the documentation here Database Generated Options

罪#恶を代价 2024-10-29 20:24:55

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

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

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

NOT NULL column means that property is not nullable and it must have a value in your entity. If you do not specify value in value type like DateTime the default value will be persisted. Default value for DateTime is DateTime.MinValue.

As I know EF doesn't support scenario where you can use NOT NULL column and not send any value from your application. The only exception is when you set StoreGeneratedPattern for the property to Identity or Computed but in such case you will not be able to set the value in the application.

So you can set value in application or in database. Not in both.

情场扛把子 2024-10-29 20:24:55

可能 DateCreated 列是 smalldatetime 并且需要是 datetime 类型?尝试更改 Visual Studio 或 Management Studio 中的列类型。

Possibly the DateCreated column is a smalldatetime and needs to be a datetime type? Try changing the column type in Visual Studio, or Management Studio.

最好是你 2024-10-29 20:24:55
  1. 设置 DateCreated 允许为 null
  2. 为 INSERT 添加触发器

    创建触发器 [dbo].[ItemCreated]

    ON [dbo].[myTable]

    插入后

    AS

    更新 [dbo].[myTable]

    SET [创建日期] = GETDATE()

    WHERE [ID] IN (SELECT DISTINCT [ID] FROM [Inserted]) AND [DateCreated] is NULL

  1. Set the DateCreated allow null
  2. Add a trigger for INSERT

    CREATE TRIGGER [dbo].[ItemCreated]

    ON [dbo].[myTable]

    AFTER INSERT

    AS

    UPDATE [dbo].[myTable]

    SET [DateCreated ] = GETDATE()

    WHERE [ID] IN (SELECT DISTINCT [ID] FROM [Inserted]) AND [DateCreated] is NULL

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文