C# 实体框架中的字符串长度不正确
我正在一个项目中使用EF6(代码优先) 通过以下方式: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]
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
asnvarchar(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字段名)。它比我们想象的更通用:)谢谢你的回答。今晚我将尝试它,并让您不断更新。这看起来像是一个解决方案,只需对您的代码做一点小改动。我更新你的答案。非常感谢。