我在项目中使用EF6(Code First)。
通过以下课程:
public class State
{
public int ID { get; set; }
[Required]
[StringLength(10)]
public string Code { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
public Country Country { get; set; }
}
我希望在数据库中Code
为nvarchar(10)
,但我得到nvarchar(3)
。我看到了Name
列的正确长度,但无法弄清楚为什么Code
未正确创建。
编辑: 我有国家课程如下:
public class Country
{
[Key]
[StringLength(3)]
public string Code { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
}
我认为,EF认为State类中的Code是Country类中的Code,因为它们之间存在关联。
现在,问题是如何告诉EF,State类中的Code不是Country类的外键?
答案 0 :(得分:3)
使用MaxLength
代替,EF将决定在创建数据库时创建字符串值字段的大小。
StringLength
是数据注释,用于验证用户输入。
MSDN:
MaxLength - 指定属性中允许的数组或字符串数据的最大长度。
StringLength - 指定数据字段中允许的最小和最大字符长度。
使用[ForeignKey("CountryCode")]
属性,将Code
课程中的Country
更改为CountryCode
(或您喜欢的任何内容),并按Column["Code"]
属性指定列名称:
public class State
{
public int ID { get; set; }
[Required]
[StringLength(10)]
public string Code { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[ForeignKey("CountryCode")]
public Country Country { get; set; }
}
public class Country
{
[Key]
[StringLength(3)]
[Column["Code"]]
public string CountryCode { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
}
MSDN链接:Column Attribute,ForeignKey Attribute
或者只需将Code
更改为StateCode
和CountryCode
并使用[ForeignKey("CountryCode")]
属性。
答案 1 :(得分:2)
由于您指的是State model
中的另一个类,它将根据属性的名称为您创建一个外键,以避免让EF
决定列的名称为您在州类中添加以下内容:
public string CountryId { get; set; }
如果您想选择CountryId
以外的其他名称,假设您要将其更改为CountryForeignKey
,则可以使用以下内容:
using System.ComponentModel.DataAnnotations.Schema;
.
.
.
[ForeignKey("CountryForeignKey")]
public Country Country { get; set; }
public string CountryForeignKey { get; set; }
答案 2 :(得分:2)
即使长时间使用它,EF仍然让我感到惊讶。到目前为止,我一直在想,默认情况下,EF正在搜索名为{Navigation Property Name}{Referenced Entity PK Property Name}
的属性作为默认的显式FK属性。但是对于您的样本(已验证),似乎对名为{Referenced Entity PK Property Name}
的属性也是如此。
由于ForeignKey
属性不能用于指定表列名称(它只能指定FK / navigation 属性名称),如果要保留完全按照它们的模型类,你应该使用MapKey
流畅的配置,例如:
modelBuilder.Entity<State>()
.HasRequired(s => s.Country)
.WithMany(s => s.States)
.Map(s => s.MapKey("CountryCode"));