HasColumnType和Database生成的正确用法是什么

时间:2014-06-14 21:26:07

标签: c# entity-framework fluent-interface

我正在将大约EF模型的~80个从EF4迁移到EF6,我也将它从Designer EDMX生成的数据库更改为Code First数据库。

现在我正在使用EF fluent-api配置实体关系,我不确定我是否正确使用它。

SQL Server数据库中的类型是varchar(50),所以我应该这样配置吗?

        mb.Entity<SomeObject>()
            .Property(so => so.Type)
            .IsUnicode(false)
            .HasColumnName("Type")
            .HasColumnType("varchar")
            .HasMaxLength(50)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

或者像这样,没有HasMaxLength(50)

        mb.Entity<SomeObject>()
            .Property(crt => crt.Type)
            .IsUnicode(false)
            .HasColumnName("Type")
            .HasColumnType("varchar(50)")
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

另外,假设我有另一个带有GUID ID的对象:

    mb.Entity<AnotherObject>()
        .Property(ao => ao.ID)
        .HasColumnName("ID")
        .HasColumnType("uniqueidentifier")
        .IsRequired()
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

在数据库中,默认值为newsequentialid(),我应该使用DatabaseGeneratedOption.NoneDatabaseGeneratedOption.Identity还是DatabaseGeneratedOption.Computed进行配置?

这些选项有什么区别? 此外,在代码中,GUID主要在对象实例化时分配,如下所示:

Guid ID = new Guid.NewGuid()

这是否合适?

2 个答案:

答案 0 :(得分:12)

varchar(50)本身不是列类型,&#39; varchar&#39;是数据类型,而(50)是字符串中字符的最大长度。 你必须这样做

mb.Entity<SomeObject>()
            .Property(so => so.Type)
            .IsUnicode(false)
            .HasColumnName("Type")
            .HasColumnType("varchar")
            .HasMaxLength(50)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

对于你的第二个问题,如果你不给GUID,它将在数据库的设置中设置为GUID的默认值,如果你想设置它,使用GUID生成器类。

答案 1 :(得分:2)

我不是这些内容如何在内部实施的专家,但我不能告诉你我从使用它们时得到的知识。

关于使用HasColumnType方法的第一个问题,如下所示:

HasColumnType("varchar(50)")

实体框架无法识别类型&#34; varchar(50)&#34;但它识别类型&#34; varchar&#34;。与ef一起使用的唯一正确用法(在版本6中检查)是:

.HasColumnType("varchar")
.HasMaxLength(50)

关于第二个问题 - DatabaseGeneratedOption。根据我对EF的经验,DatabaseGeneratedOption.Computed和DatabaseGeneratedOption.None之间没有区别 - 它对它们的处理方式是一样的。仅对DatabaseGeneratedOption.Identity进行区分 - 在这种情况下,列被定义为标识列,并且在从应用程序向数据库插入数据期间传递给它的值将被忽略,而是由数据库分配。如果将列定义为DatabaseGeneratedOption.None或DatabaseGeneratedOption.Computed,则需要为显示的ID列提供值:

Guid ID = new Guid.NewGuid()

否则,它将尝试始终为GUID分配默认值(所有数字设置为零)。如果将列指定为DatabaseGeneratedOption.Identity,则在将其保存到db之前,无需关心为ID分配值。相反,它将由dbms设置为默认值(在您的情况下为&#34; newsequentialid()&#34;)。所以正确的选择是DatabaseGeneratedOption.Identity。