C# 实体框架中的字符串长度不正确

C# 实体框架中的字符串长度不正确,c#,entity-framework-6,data-annotations,C#,Entity Framework 6,Data Annotations,我正在一个项目中使用EF6(代码优先) 通过以下方式: 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]

我正在一个项目中使用EF6(代码优先)

通过以下方式:

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
as
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类中的代码就是Country类中的代码,因为它们之间存在关联

现在,问题是我应该如何告诉EF State类中的代码不是Country类的外键?

相反,EF将在创建数据库时决定字符串值字段的大小

是数据注释,用于验证用户输入

MSDN:

MaxLength-指定属性中允许的数组或字符串数据的最大长度

StringLength-指定数据字段中允许的最小和最大字符长度

问题更新后: 使用
[ForeignKey(“CountryCode”)]
atribute,将
Country
类中的
code
更改为
CountryCode
(或您喜欢的任何内容),并通过
列[“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链接:


或者只需将您的
code
s更改为
StateCode
CountryCode
,并使用
[ForeignKey(“CountryCode”)]
属性。

因为您引用的是
状态模型中的另一个类
,它将根据属性的名称为您创建一个外键,因此,为了避免让
EF
决定列的名称,请在state类中添加以下内容:

public string CountryId { get; set; } 
如果要选择除
CountryId
以外的其他名称,假设要将其更改为
CountryForeignKey
,则可以使用以下选项:

 using System.ComponentModel.DataAnnotations.Schema;
.
.
.
[ForeignKey("CountryForeignKey")]
        public Country Country { get; set; }

        public string CountryForeignKey { get; set; } 
这就是你在数据库中得到的

即使使用了很长时间,EF仍然让我感到惊讶。到目前为止,我一直认为默认情况下,EF正在搜索名为
{Navigation property Name}{Referenced Entity PK property Name}
的属性作为默认显式FK属性。但是对于您的示例(已验证),它似乎对名为
{Referenced Entity PK property Name}
的属性也有相同的作用

由于
ForeignKey
属性不能用于指定表列名(它只能指定FK/导航属性名),因此如果要保持模型类的原样,应使用
MapKey
fluent配置,例如:

modelBuilder.Entity<State>()
    .HasRequired(s => s.Country)
    .WithMany(s => s.States)
    .Map(s => s.MapKey("CountryCode"));
modelBuilder.Entity()
.HasRequired(s=>s.Country)
.有许多州(s=>s州)
.Map(s=>s.MapKey(“国家代码”);

您使用的是数据库优先还是代码优先?我使用的是代码优先。那么,问题出在哪里?它是否给出了错误或异常,或者只是生成了错误的代码?没有错误。数据库创建时不存在任何错误。只有列长度不正确。您在配置中是否添加了任何约定?我使用了[MaxLength(10)],但没有更改!!我想我找到了原因。我更新了我的问题,请告诉我该怎么做。@FLICKER实际上这里不需要
MaxLength
,因为StringLength也会推断字符串字段的大小。但是有人说,codefirst中有一些不同。是的,他们之间没有建立任何关系,对吗?实际上,州应该指国家,但不指州。代码。我知道房产名称的相似性让EF感到困惑,但有没有办法在不改变房产名称的情况下纠正这个问题?谢谢你的回答。我将检查另一个答案,并选择一个更适合我的答案。我得出了同样令人惊讶的结论,还发现在
状态中包含属性
CountryCode
,可以让EF再次正确推断关联(当然,如果
CountryCode
是实际的FK字段名)。它比我们想象的更通用:)谢谢你的回答。今晚我将尝试它,并让您不断更新。这看起来像是一个解决方案,只需对您的代码做一点小改动。我更新你的答案。非常感谢。