实体框架

时间:2017-11-01 05:21:04

标签: c# entity-framework-6 data-annotations

我在项目中使用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; }
}

我希望在数据库中Codenvarchar(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类的外键?

3 个答案:

答案 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 AttributeForeignKey Attribute

或者只需将Code更改为StateCodeCountryCode并使用[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; } 

这就是你在数据库中得到的 enter image description here

答案 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"));