外键在数据库中重复

时间:2013-01-23 20:21:01

标签: 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]
    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; }
}

这是我的OnModelCreating,可能是错误所在:

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       // modelBuilder.Entity<Contract>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Contract>().HasRequired(bm => bm.Article).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Contract>().HasRequired(bm => bm.Client ).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Article>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Measurement>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Order>().HasRequired(bm => bm.Client).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Order>().HasRequired(bm => bm.Article).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<IncomingMeasurement>().HasRequired(bm => bm.client).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Client>().HasOptional(c => c.MerchantReference).WithMany().HasForeignKey(c => c.MerchantReferenceID);

        //Required fields


        base.OnModelCreating(modelBuilder);
    }

我的db(我的sql server)中发生了一些奇怪的事情,即这是我的创建表模式。

这些是我的字段:

CREATE TABLE [dbo].[Contracts](
[ContractID] [int] IDENTITY(1,1) NOT NULL,
[PricePerUnit] [float] NOT NULL,
[Unit] [int] NOT NULL,
[Currency] [int] NOT NULL,
[ClientID] [int] NOT NULL,
[CompanyID] [int] NOT NULL,
[ArticleID] [int] NOT NULL,
[Client_ClientID] [int] NOT NULL,
[Article_ArticleID] [int] NOT NULL,
[Client_ClientID1] [int] NULL,
[Article_ArticleID1] [int] NULL,

如果您注意到,[Client_ClientID]在[Article_ArticleID1]中有一个副本:[Client_ClientID1]和[Article_ArticleID]。 但公司没有。

有关如何解决这个问题的想法吗?

2 个答案:

答案 0 :(得分:1)

这是因为您在实体类中包含冗余(外键)列。例如,查看Contract类中的类别。

public class Contract
{
    public Int32 CategoryID { get; set; }

    public virtual Category Category { get; set; }
}

您手动指定属性,因此指定列CategoryID,然后实体框架生成另一列以保存属性Category引用的Category的外键。

如果您需要引用类别的ID,请删除属性CategoryID并使用contract.Category.CategoryID

更新

我不知道包含外键属性的建议,但是看看评论中链接的文章Jeff Siever的答案我可能在配置非常规外键名称一节中找到了答案。

实体框架使用约定来匹配导航属性的名称和外键属性,当您使用NavigationPropertyNameId大写{时,默认约定为NavigationPropertyName_IdNavigationPropertyNameID {1}}。

所以你有几个选择 - 改变命名以使用D,替换约定或覆盖约定。

答案 1 :(得分:0)

消除模型中的重复信息。不需要引用对象的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上的Required属性,你需要设置你的实体,以便孩子们是必需的。