ASP.NET MVC Code First: 角色关系中的多重性无效

3
我有一个简单的关系。一项活动与两个页面相关联。一个页面只能与一个活动相关联。但我一直遇到这个错误:
System.Data.Edm.EdmAssociationEnd: : 在关系“Page_Campaign”中,“Page_Campaign_Source”角色中的多重性无效。因为从属角色属性不是关键属性,所以从属角色的上限必须是“*”。
我查看了一些示例代码和教程,同时将其与我的代码进行比较,但我找不到错误。
 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; }
}

编辑

按照Eranga的回答,使用Fluent API进行操作,但现在出现了以下错误:

保存实体时出现错误,因为它们的关系没有公开外键属性。


我只是想知道,在Campaign类中,为什么你只有页面的虚拟对象而没有它们的外键,而在Page类中,你既有外键又有Campaign的虚拟对象? - st mnmn
RedeemPage 是另一个类吗?还是实际上应该是 Page 类? - Slauma
@stmnmn 因为外键在关系的“一”侧。 - Reinard
@Slauma RedeemPage 继承自 Page。 - Reinard
你尝试过“清理并构建”吗?;D - Karel-Jan Misseghers
2个回答

2
数据注释映射在这种情况下会令人困惑。使用流畅的API进行配置。删除导航属性映射的数据注释,并按以下方式使用流畅的API。
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);
    }
}

编辑

在设置WillCascadeOnDelete(false)之后,问题在于CampaignPage都有自增的主键,并且你有一个一对一的映射关系。因此,为了保存一条记录,需要另一行插入的Id,而那一行需要第一行的id。

你可以将PK更改为GUID或使1个FK为空并调用两次SaveChanges

将关系更改为可空

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

看起来很合理,但我会创建一个接口或抽象超类Page。不过我不知道整个上下文是什么,所以随便了 :p - Karel-Jan Misseghers
我可以将Fluent API与数据注释混合使用吗?(这样我就不必重新编写所有的类了) - Reinard
@SirTroll 你可以混用,但在某些情况下,当EF与映射混淆时,可能会遇到问题 :) - Eranga
@Eranga 谢谢你的帮助。还有一些问题,我已经更新了 OP。 - Reinard

0

我认为你的活动应该有一个页面集合,而不是2个子实体。

我已经有一段时间没有编写MVC代码了,但如果我记得正确的话,应该是这样的:

public virtual Collection<Page> pages

在其中您可以放置您的2个页面


一个广告活动有两个页面(不多不少),一个常规页面和一个兑换页面。因此,我不能使用集合。 - Reinard
1
你是说你没有接口或抽象超类?这是什么魔法!? - Karel-Jan Misseghers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接