ASP.NET MVC Code First: Multiple Invalid In Role In Relationship

I have a simple connection. The campaign is linked to two pages. A page can only be associated with one campaign. But I keep running into this error:

System.Data.Edm.EdmAssociationEnd :: multiplicity is not valid in role 'Page_Campaign_Source' in relation to 'Page_Campaign'. Since the Dependent Role Properties are not key properties, the upper bound for the multiplicity of the dependent role must be "*".

I have looked at some sample codes and tutorials comparing them to my code, but cannot find the error.

 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

Then came Eranga's answer and used the Fluent API, but now I get:

An error occurred while saving objects that do not map to the foreign key of a property for their relationship

+3


source to share


2 answers


The display of data annotations is confusing in this scenario. Use the Fluent API for customization. Remove the data annotations for mapping navigation properties and use the fluent API as shown below.

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 installation WillCascadeOnDelete(false)

is that both Campaign

and Page

have auto-incrementing PKs and you have a 1 to 1 mapping. Hence, keeping one record requires the id of the other inserted row, and the other row needs the id of the 1st row.



You can change PK as GUID or make 1 FK equal to zero and call twice SaveChanges

. For example,

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


source


I think you should have a collection of pages in your campaign instead of 2 child objects,

it's been a while since I was last coded in MVC, but if I remember correctly it should look something like this:



public virtual Collection<Page> pages

      

in which you put your 2 pages

0


source







All Articles