First, ASP.NET MVC code: Multiplicity is not acceptable in relationship roles.

asp.net c# entity-framework

Question

I have a simple relationship. A campaign is linked to two Pages. A page can only be linked to one campaign. But I keep running into this error:

System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'Page_Campaign_Source' in relationship 'Page_Campaign'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

I went looking through some example codes and tutorials while comparing it to my code but I can't find a mistake.

 public class Campaign
    {
        [Key()]
        public int Campaignid { get; set; }
        public string Name { get; set; }

        public virtual Page LandingPage { get; set; }
        public virtual RedeemPage RedeemPage { get; set; }
    }


public class Page
{
    [Key()]
    public int PageContentId { get; set; }
    public string Logo { get; set; }
    public string Css { get; set; }

    [ForeignKey("Campaign")]
    public int campaignID { get; set; }
    public virtual Campaign Campaign { get; set; }
}

Edit

Followed Eranga's reply and used the Fluent API instead but now I'm getting:

An error occurred while saving entities that do not expose foreign key properties for their relationships

1
3
10/9/2015 2:30:00 PM

Accepted Answer

The Data annotations mapping is confusing in this scenario. Use the Fluent API to configure. Remove the data annotations for navigational property mapping and use fluent API as follows.

class MyContext : DbContext
{

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Campaign>().HasRequired(x => x.LandingPage)
           .WithMany();

        modelBuilder.Entity<Page>().HasRequired(x => x.Campaign)
           .WithMany()
           .HasForeignKey(x => x.campaignID); 

      base.OnModelCreating(modelBuilder);
    }
}

Edit

The problem after setting WillCascadeOnDelete(false) is that both Campaign and Page has auto incremented PKs and you have a 1-to-1 mapping. Hence to save one record it needs the Id of the other inserted row and that other row need the id of the 1st row.

You can either change the PK to be a GUID or make 1 FK to be nullable and call to SaveChanges twice. Eg

Changing the relationship to nullable

    modelBuilder.Entity<Campaign>().HasOptional(x => x.LandingPage)
       .WithMany();


using(var scope = new TransactionScope())
{

       context.Campaigns.Add(campaign);
       context.SaveChanges();

       page.CampaignId = campaign.CampaignId;
       context.Pagess.Add(page);
       context.SaveChanges();

       scope.Complete();
}
2
3/27/2012 11:42:46 AM

Popular Answer

I think you should have a collection of pages in your campaign, instead of the 2 children-entities,

has been a while since I've last coded in MVC but if I recall correctly it should be something like:

public virtual Collection<Page> pages

in which you then put your 2 pages



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