EF6 Code First"外键多重性在角色"中无效。

时间:2014-06-06 20:33:24

标签: c# entity-framework ef-code-first entity-framework-6

我对EF有点新鲜。我的情况不是那么独特,但我一直无法找到一个好的答案。

我有三张桌子。前两个是CompanyClientClient有一个CompanyId外键返回给他们的客户。 CompanyClient都有一个AddressId表的Address外键。

我已经通过地址表消除了级联删除,以消除循环级联。现在,当我尝试生成我的数据库时,我得到:

  

Multiplicity在Role' Client_Address_Source'中无效。在关系' Client_Address'。由于Dependent Role属性不是关键属性,因此Dependent Role的多重性的上限必须为' *'。

我在公司表上也遇到了同样的错误。这是我的实体(代码缩写为post): *已修改以包含更多详细信息

namespace ForeignKeyExample.DataModel
{
    [Table("Address")]
    public class Address
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int AddressId { get; set; }
        public int AddressTypeId { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string PostalCode { get; set; }
    }
}

namespace ForeignKeyExample.DataModel
{
    [Table("Company")]
    public class Company
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CompanyId { get; set; }
        public string Name { get; set; }
        public int? AddressId { get; set; }

        [ForeignKey("AddressId")]
        public Address Address { get; set; }
    }
}

namespace ForeignKeyExample.DataModel
{
    [Table("Client")]
    public class Client
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ClientId { get; set; }
        public string Name { get; set; }
        public int? AddressId { get; set; }
        public int CompanyId { get; set; }

        [ForeignKey("AddressId")]
        public Address Address { get; set; }

        [ForeignKey("CompanyId")]
        public Company Company { get; set; }
    }
}

namespace ForeignKeyExample
{
    public class ExampleContext : DbContext
    {
        public ExampleContext() : base("name=ExampleContext"){  this.Configuration.ProxyCreationEnabled = false; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Client>().HasOptional(a => a.Address).WithOptionalDependent().WillCascadeOnDelete(false);
            modelBuilder.Entity<Company>().HasOptional(a => a.Address).WithOptionalDependent().WillCascadeOnDelete(false);
        }

        public DbSet<Address> Addresses { get; set; }
        public DbSet<Company> Companies { get; set; }
        public DbSet<Client> Clients { get; set; }
    }
}

也许有一些方法可以流畅地#34;解决OnModelCreating中的问题?这个错误让我相信(我已经在其他帖子中看到)EF希望我翻转引用并让地址表引用回公司或客户端,但这意味着我需要两个地址表,这似乎是蹩脚的。任何帮助表示赞赏。

感谢
布兰登

*修改
根据评论中的要求,我在上面的课程中添加了更多细节。这三个模型类位于主项目下的子文件夹模型中。 EF6安装在项目中。如前所述,OnModelCreating中的两行是删除关系中的循环引用,如果删除了可选的Address项,则删除级联。运行enable-migrations后,我收到上面列出的错误。希望这将使其可重现。感谢你们的评论。

2 个答案:

答案 0 :(得分:0)

只想分享这个问题的积极解决方案 - 即使在这种情况下不相关 - 这适用于VS2012:

1)为项目选择.edmx。这 - 希望 - 显示数据库/表和“模型浏览器”的图表,MB。

2)在MB中打开“关联”并单击相关性的FK_定义。

3)在“属性”中查看“End1 Multiplicity”和“End2 Multiplicity”并将其适当更改为例如'0 ... 1(零或一个任务)'。

在我的情况下,我忘了在定义表时将字段定义为'Nullable'并随后更改它。因此在我的MVC项目中遇到问题,当基础发生变化时,它不会自行重新配置。纠正这是一个挑战,这个修复是最后一件事要改变.-)

到目前为止,我只是MVC的初学者......

答案 1 :(得分:0)

只需注释掉OnModelCreating中的两行就可以修复错误。 生成ED迁移并查看生成的表,我认为它们就是你想要的外键:

        CreateTable(
            "dbo.Address",
            c => new
                {
                    AddressId = c.Int(nullable: false, identity: true),
                    AddressTypeId = c.Int(nullable: false),
                    Address1 = c.String(),
                    Address2 = c.String(),
                    City = c.String(),
                    State = c.String(),
                    PostalCode = c.String(),
                })
            .PrimaryKey(t => t.AddressId);

        CreateTable(
            "dbo.Client",
            c => new
                {
                    ClientId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    AddressId = c.Int(),
                    CompanyId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.ClientId)
            .ForeignKey("dbo.Address", t => t.AddressId)
            .ForeignKey("dbo.Company", t => t.CompanyId, cascadeDelete: true)
            .Index(t => t.AddressId)
            .Index(t => t.CompanyId);

        CreateTable(
            "dbo.Company",
            c => new
                {
                    CompanyId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    AddressId = c.Int(),
                })
            .PrimaryKey(t => t.CompanyId)
            .ForeignKey("dbo.Address", t => t.AddressId)
            .Index(t => t.AddressId);

关于级联删除,如果外键可以为空,则Code First不会在关系上设置级联删除,并且当删除主体时,外键将设置为null。因此,如果您不在此处进行显式映射,则级联删除设置为false。