C# 数据库中的外键重复
一些外键在我的合同表中被创建。(文章和客户)。公司也可以 我的模型:C# 数据库中的外键重复,c#,entity-framework,ef-code-first,entity-framework-5,C#,Entity Framework,Ef Code First,Entity Framework 5,一些外键在我的合同表中被创建。(文章和客户)。公司也可以 我的模型: public class Contract { [Key] public int ContractID { get; set; } public double PricePerUnit { get; set; } public int Unit { get; set; } public int Currency { get; set; } [Required] publ
public class Contract {
[Key]
public int ContractID { get; set; }
public double PricePerUnit { get; set; }
public int Unit { get; set; }
public int Currency { get; set; }
[Required]
public int ClientID { get; set; }
public virtual Client Client { get; set; }
[Required]
public int CompanyID { get; set; }
public virtual Company Company { get; set; }
[Required]
public int ArticleID { get; set; }
public virtual Article Article { get; set; }
}
public class Client {
[Key]
public int ClientID { get; set; }
public string Number { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string Memo { get; set; }
public bool isMerchant { get; set; }
public string Name
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
//[Required]
public int? MerchantReferenceID { get; set; }
public virtual Client MerchantReference { get; set; }
[Required]
public int CompanyID { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Company
{
[Key]
public int CompanyID { get; set; }
public string Name { get; set; }
public int DeviceIncomingWeight { get; set; }
public string ZipCode { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public bool Admin { get; set; }
public int UnitForMeasurements { get; set; }
public int UnitForDisplayOnDocuments { get; set; }
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Article> Articles { get; set; }
public virtual ICollection<Client> Clients { get; set; }
public virtual ICollection<Location> Locations { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
public virtual ICollection<IncomingMeasurement> IncomingMeasurements { get; set; }
public virtual ICollection<Measurement> Measurements { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Article {
[Key]
public int ArticleID { get; set; }
[Required]
public string Code { get; set; }
public string Name { get; set; }
public bool TrackStock { get; set; }
public int CurrentStock { get; set; }
public double? Price { get; set; }
[Required]
public int CompanyID { get; set; }
public virtual Company Company { get; set; }
[Required]
public int CategoryID { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
如果您注意到,[Client\u ClientID]在[Article\u ArticleID1]中有一个重复的:[Client\u client1]和[Article\u ArticleID]。
但公司没有
关于如何解决这个问题有什么想法吗?从模型中删除重复信息。引用对象的id是不需要的,是导致问题的原因
public class Contract {
[Key]
public int ContractID { get; set; }
public double PricePerUnit { get; set; }
public int Unit { get; set; }
public int Currency { get; set; }
public virtual Client Client { get; set; }
public virtual Company Company { get; set; }
public virtual Article Article { get; set; }
}
您需要设置实体,而不是id上的必需属性,这样子实体才是必需的。之所以会出现这种情况,是因为实体类中包含了冗余(外键)列。例如,查看
合同
类中的类别
public class Contract
{
public Int32 CategoryID { get; set; }
public virtual Category Category { get; set; }
}
您可以手动指定一个属性,从而指定列CategoryID
,然后实体框架生成另一列来保存属性类别所引用的类别的外键
因此,如果需要引用类别的ID,只需删除属性CategoryID
,并使用contract.Category.CategoryID
更新
我没有意识到包含外键属性的建议,但查看Jeff Siever答案评论中链接的文章,我可能在配置非常规外键名称部分找到了答案
实体框架使用约定来匹配导航属性和外键属性的名称,默认约定是NavigationPropertyNameId
或NavigationPropertyName\u Id
,而您使用大写的NavigationPropertyNameId
因此,您有多种选择—将命名更改为使用Id
、替换约定或覆盖约定。我过去曾这样做过,但所有官方消息来源都表示,最好也将int添加为外键。例如。我还看到了脚手架的一些改进,这可能是它更好的一个标志:)我在文章和客户中遇到了脚手架问题,这正是我现在遇到这个问题的地方。我不认为这是真正的解决方案,我在过去做过,它在controller+视图中没有生成脚手架,所以在证明错误之前,我正在寻找一个更好的答案。即使是Scott Hanselmans示例项目也按照我的方式进行(尽管我在某个地方犯了一个错误)。刚刚看到你的onmodel创建。为什么指定属性需要两次?您已经在适当的属性上获得了required属性,然后在模型创建中指定HasRequired。我相信这是问题的根源。尤其是因为公司还可以,而且合同中的HasRequired行被注释掉了。如果我没有在我的“onModelBuilder”中添加:。WillCascadeOnDelete(false),我会收到一个ms sql server的外键生成错误。但事实上,错误可能就在某个地方。但我仍然需要添加WillCascadeOnDelete(false),因此我的db架构将创建。您是否尝试从模型中删除必需的属性?配置中的WithRequired仍应强制外键不允许为null。请参阅我对另一个答案的评论:)我阅读了它,希望它有助于发现问题-请参阅我的更新。更改视图、模型、代码,…-)将更新您上!有一个关于的后续问题:。因为您在这里回答了我的问题,所以仍然显示了另一个属性。(感谢您解决问题1!:-)
public class Contract {
[Key]
public int ContractID { get; set; }
public double PricePerUnit { get; set; }
public int Unit { get; set; }
public int Currency { get; set; }
public virtual Client Client { get; set; }
public virtual Company Company { get; set; }
public virtual Article Article { get; set; }
}
public class Contract
{
public Int32 CategoryID { get; set; }
public virtual Category Category { get; set; }
}