【问题标题】:EF6 Code First "Foreign Key Multiplicity is not valid in Role"EF6 代码优先“外键多重性在角色中无效”
【发布时间】:2014-07-28 05:12:01
【问题描述】:

我对 EF 有点陌生。我的情况不可能那么独特,但我一直无法找到一个好的答案。

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

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

多重性在关系“Client_Address”中的角色“Client_Address_Source”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是'*'。

我在 Company 表上也遇到了同样的错误。这是我的实体(代码缩写为 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; }
    }
}

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

谢谢
布兰登

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

【问题讨论】:

  • 我感觉你剪得太多了。
  • 您找到解决方案了吗?遇到类似的问题。

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


【解决方案1】:

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

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

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

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

在我的情况下,我在定义表时忘记将字段定义为“可空”并随后对其进行了更改。因此在我的 MVC 项目中遇到问题,当基础更改时,它不会自行重新配置。纠正这是一个挑战,而这个修复是最后要改变的。-)

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

【讨论】:

    【解决方案2】:

    只需注释掉 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不会对关系设置级联删除,删除主体时外键会设置为空。因此,如果您不在这里进行显式映射,级联删除将设置为 false。

    【讨论】:

      猜你喜欢
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多