EF6 Code First "Foreign Key Multiplicity is not valid in Role"

c# ef-code-first entity-framework entity-framework-6

Question

I'm somewhat new to EF. My situation can't be that unique, but I've been unable to find a good answer for it.

I have three tables. First two are Company and Client. Client has a CompanyId foreign key back to the company whose client they are. Both Company and Client have an AddressId foreign key to an Address table.

I have eliminated cascading deletes through the Address table to eliminate the cirular cascade. Now though, when I try to generate my database I get:

Multiplicity is not valid in Role 'Client_Address_Source' in relationship 'Client_Address'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

I get the same error on the Company table as well. Here are my entities (code abbreviated for post): *Edited to include more detail

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; }
    }
}

Perhaps there is some way to "fluently" solve the issue in OnModelCreating? The error leads me to believe (and I've seen in other posts) that EF wants me to flip the reference and have the Address table refer back to the Company or Client, but that would mean I would need two address tables, which seems, well, lame. Any help appreciated.

Thanks
Brandon

*EDIT
As requested in comments, I have added more detail in the classes above. The three model classes are in a subfolder Model under the main project. EF6 is installed on the project. As mentioned before, the two lines in OnModelCreating are to remove the circular reference in the relationship and remove the cascade if an optional Address item is deleted. After running enable-migrations I receive the error listed above. Hopefully this will make it reproducable. Thanks for commenting guys.

1
3
6/9/2014 1:56:02 PM

Popular Answer

Just commenting out the two lines in your OnModelCreating fixes the error. Generating the ED migration and looking at the generated tables, I think they are what you wanted in terms of foreign keys:

        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);

About the cascade delete, if the foreign key is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null. So if you don't do an explicit mapping here the cascade delete is set to false.

0
10/12/2016 9:25:55 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow