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
source to share
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();
}
source to share