Entity Framework 中的字符串长度不正确
Incorrect String Length in Entity Framework
我在项目中使用 EF6 (Code First)。
通过 class:
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
没有正确创建。
编辑:
我的国家 class 如下:
public class Country
{
[Key]
[StringLength(3)]
public string Code { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
}
我认为,EF 认为州 class 中的代码是国家 class 中的代码,因为它们之间存在关联。
现在,问题是我应该如何告诉 EF 状态 class 中的代码不是国家 class 的外键?
改用MaxLength
,EF会在创建数据库时决定字符串值字段的大小。
StringLength
是数据注解,用于验证用户输入。
MSDN:
MaxLength - Specifies the maximum length of array or string data allowed in a property.
StringLength - Specifies the minimum and maximum length of characters that are allowed in a data field.
问题更新后:
使用 [ForeignKey("CountryCode")]
属性,将 Country
class 中的 Code
更改为 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")]
属性。
由于您在 State model
中引用另一个 class 它将根据属性名称为您创建一个外键,因此避免让 EF
决定什么列的名称为您添加以下状态 class :
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
属性不能用于指定table列名称(它只能指定FK/navigation 属性 name),如果你想保持模型 类 原样,你应该使用 MapKey
fluent 配置,例如:
modelBuilder.Entity<State>()
.HasRequired(s => s.Country)
.WithMany(s => s.States)
.Map(s => s.MapKey("CountryCode"));
我在项目中使用 EF6 (Code First)。
通过 class:
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
没有正确创建。
编辑: 我的国家 class 如下:
public class Country
{
[Key]
[StringLength(3)]
public string Code { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
}
我认为,EF 认为州 class 中的代码是国家 class 中的代码,因为它们之间存在关联。
现在,问题是我应该如何告诉 EF 状态 class 中的代码不是国家 class 的外键?
改用MaxLength
,EF会在创建数据库时决定字符串值字段的大小。
StringLength
是数据注解,用于验证用户输入。
MSDN:
MaxLength - Specifies the maximum length of array or string data allowed in a property.
StringLength - Specifies the minimum and maximum length of characters that are allowed in a data field.
问题更新后:
使用 [ForeignKey("CountryCode")]
属性,将 Country
class 中的 Code
更改为 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")]
属性。
由于您在 State model
中引用另一个 class 它将根据属性名称为您创建一个外键,因此避免让 EF
决定什么列的名称为您添加以下状态 class :
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
属性不能用于指定table列名称(它只能指定FK/navigation 属性 name),如果你想保持模型 类 原样,你应该使用 MapKey
fluent 配置,例如:
modelBuilder.Entity<State>()
.HasRequired(s => s.Country)
.WithMany(s => s.States)
.Map(s => s.MapKey("CountryCode"));