C# HasColumnType和数据库生成的正确用法是什么

C# HasColumnType和数据库生成的正确用法是什么,c#,entity-framework,fluent-interface,C#,Entity Framework,Fluent Interface,我正在将大约80个实体的EF模型从EF4迁移到EF6,我还将它从Designer EDMX生成的数据库更改为代码优先数据库 现在,我正在使用EF fluent api配置实体关系,但我不确定我是否正确 它在SQL Server数据库中的类型是varchar(50),所以我应该这样配置它吗 mb.Entity<SomeObject>() .Property(so => so.Type) .IsUnicode(fals

我正在将大约80个实体的EF模型从EF4迁移到EF6,我还将它从Designer EDMX生成的数据库更改为代码优先数据库

现在,我正在使用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);
此外,假设我有另一个GUID ID为的对象:

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

这是否合适?

我不是这些东西如何在内部实现的专家,但我无法告诉您我从使用它们中了解到了什么

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

HasColumnType("varchar(50)")
实体框架不识别类型“varchar(50)”,但它识别类型“varchar”。与ef(在版本6中检查)一起使用的唯一正确用法是:

关于第二个问题——数据库生成选项。根据我对EF的经验,DatabaseGeneratedOption.Computed和DatabaseGeneratedOption.None之间没有区别——它对它们的处理是一样的。只有DatabaseGenerateOption有区别。Identity-在这种情况下,列定义为Identity列,在从应用程序向db插入数据时传递给它的值将被忽略,而由数据库分配。如果将列定义为DatabaseGeneratedOption.None或DatabaseGeneratedOption.Computed,则需要为ID列提供值,如图所示:

Guid ID = new Guid.NewGuid()
否则,它将尝试始终为GUID分配默认值(所有数字都设置为零)。如果将列指定为DatabaseGeneratedOption.Identity,则在将ID保存到db之前,无需为ID赋值。相反,它将由dbms设置为默认值(在您的示例中是“newsequentialid()”)。所以,您的正确选择是DatabaseGenerateOption.Identity。

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

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

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

谢谢,这有助于澄清问题。fluent API有时会有点混乱。更不用说这些方法的措辞是明确的,但与传统的关系数据库术语略有不同!您知道哪种方式被认为是分配guid的最佳实践吗?据我所知,让dbms分配它“更安全”,因为它将在内部防止重复的GUID,而外部分配的GUID可能会冲突?虽然区别有点学术性,因为生成GUID哈希冲突的概率很小。主键值是db的内部内容,通常您甚至不应该在应用程序端触摸它,即使是出于简单的原因。此外,在数据库方面做得越多越好。IDE是否提供了任何预定义的常量,如
varchar
varbinary
等?
.HasColumnType("varchar")
.HasMaxLength(50)
Guid ID = new Guid.NewGuid()
mb.Entity<SomeObject>()
            .Property(so => so.Type)
            .IsUnicode(false)
            .HasColumnName("Type")
            .HasColumnType("varchar")
            .HasMaxLength(50)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);