5

我们的 SQL Server 数据库表中有一个由 SQL Server 自动生成的字段,该字段称为CreatedTime.

我们已将整个数据库表映射到 Entity Framework 中的数据模型,因此也映射了字段CreatedTime

当我们通过实体框架在数据库中插入新行时,我们不会为CreatedTime.

这会导致插入失败并出现以下错误:

SqlDateTime 溢出。必须在 1753 年 1 月 1 日上午 12:00:00 到 9999 年 12 月 31 日晚上 11:59:59 之间

所以问题是:有没有办法在实体框架插入语句中排除实体数据模型中的特定字段?这样我们就不会得到上面的错误了?

我们希望将该字段保留CreatedTime在 Entity 模型中,因为我们可能希望稍后访问它。

4

5 回答 5

8

如果使用 Fluent API:

using System.ComponentModel.DataAnnotations.Schema;

this.Property(t => t.CreatedTime)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

如果使用注解

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public System.DateTime CreatedTime { get; set; }
于 2014-02-13T21:02:53.193 回答
4

我在这个线程上找到了一个简单的解决方案:

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/7db14342-b259-4973-ac09-93e183ae48bb

费尔南多·索托写道:

“如果您转到 EDM 设计器,单击数据库自动生成的表中的字段,右键单击它并选择属性并查看属性窗口单击 StoreGeneratedPattern 并将其值设置为 Computed,我相信它会给你你想要的东西。”

上述解决方案非常快速和简单,而且似乎有效。

还要感谢您的贡献,但上述解决方案似乎可以完成工作。

于 2013-05-03T07:25:17.003 回答
1

尝试在此属性上使用 NotMapped 属性 http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.notmappedattribute.aspx

于 2013-05-02T14:16:20.870 回答
1

你可以做两件事:

  1. 如果您有权访问数据库,请检查该字段是否有default值。如果不是,您可以将其设置为GETDATE(),并且该字段应正确设置,并且您不必通过实体框架添加/更新它。

  2. 如果您无权访问数据库,或者不想在那里进行任何更改,您可以更改实体数据模型的行为以自动设置日期。只需扩展您的 ObjectContext 模型。

    public partial class MyEntities 
    {
        public override int SaveChanges() 
        {
            var entityChangeSet = ChangeTracker.Entries<SomeEntity>();
            if (entityChangeSet != null)
            {
                foreach (DbEntityEntry<SomeEntity> entry in entityChangeSet )
                {
                    switch (entry.State)
                    {
                        case EntityState.Modified:
                            entry.Entity.LastModifiedDate = DateTime.UtcNow;
                            break;
                        case EntityState.Added:
                            entry.Entity.CreatedDate = DateTime.UtcNow;
                            break;
                    }
                }
            }
            return base.SaveChanges();
        }
    }
    

这样,当您添加或更新项目时,您不必为这些字段添加任何信息,模型会为您完成。如果您有多个需要此行为的实体,您可以创建一个接口并使实体类继承该接口:

public interface IHaveCreatedDate {
    DateTime CreatedDate { get; set; }
}

public partial class MyEntity : IHaveCreatedDate {
    //MyEntity already implements this!
}

然后你需要做的就是改变对 ChangeTracker 的调用:

var entityChangeSet = ChangeTracker.Entries<IHaveCreatedDate>();
于 2013-05-02T14:22:24.087 回答
0

CreatedTime可以为空吗?

一种可能的解决方法 - 如果CreatedTime不可为空:

DateTime sqlServerMinDateTime = new DateTime(1753, 1, 1, 12, 0, 1, 0);

if(myEntity.CreatedTime < sqlServerMinDateTime) 
{
    myEntity.CreatedTime = sqlServerMinDateTime;
}

// do insert here
// ....

一种可能的解决方法 - 如果CreatedTime可以为空:

DateTime sqlServerMinDateTime = new DateTime(1753, 1, 1, 12, 0, 1, 0);

if(myEntity.CreatedTime < sqlServerMinDateTime) 
{
    myEntity.CreatedTime = null;
}

// do insert here
// ....
于 2013-05-02T14:13:41.227 回答