我正在将大约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.None
,DatabaseGeneratedOption.Identity
还是DatabaseGeneratedOption.Computed
进行配置?
这些选项有什么区别? 此外,在代码中,GUID主要在对象实例化时分配,如下所示:
Guid ID = new Guid.NewGuid()
这是否合适?
答案 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。