【问题标题】:Multiplicity constraint violated. The role 'Person_Projects_Source' of the relationship 'Repository.Person_Projects' has multiplicity 1 or 0..1违反了多重性约束。关系“Repository.Person_Projects”的角色“Person_Projects_Source”具有多重性 1 或 0..1
【发布时间】:2014-02-12 15:38:07
【问题描述】:

您好之前在使用另一种数据类型时遇到过这个问题。有关更多详细信息,您可以在此处查看。 Multiplicity constraint violated Entity framework 5

但现在该解决方案不起作用或在网上找到任何其他解决方案。

我的课程是:

namespace Prometheus.Models
{
    [Table("People")]
    public class Person : IPerson, INamedEntity
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public virtual int Id { get; set; }
        [DisplayName("Prenume")]
        public virtual string FirstName { get; set; }
        [DisplayName("Nume")]
        public virtual string LastName { get; set; }

        public string Name
        {
            get
            {
                return FirstName + " " + LastName;
            }
            set { }
        }
        [DisplayName("Email")]
        public virtual string Email { get; set; }
        public DateTime? LastModified { get; set; }
        public virtual ICollection<Result> Results { get; set; }
        public virtual ICollection<Project> Projects { get; set; }
    }
}

还有

public class Project :INamedEntity
{

    public int Id { get; set; }
    public DateTime? LastModified { get; set; }
    [DisplayName("Titlu Proiect")]
    [Required]
    public string Name { get; set; }//Title
    [Required]
    [DisplayName("Tip proiect")]
    public virtual ProjectType ProjectType{ get; set; }
    [DisplayName("Status proiect")]
    public virtual ProjectStatus ProjectStatus { get; set; }
    [Required]
    [DisplayName("Tip program")]
    public virtual ProgramType ProgramType { get; set; }
    [Required]
    [DisplayName("Numar luni")]
    public int NumberOfMonths { get; set; }
    [Required]
    [DisplayName("Project title")]
    public string NameEn { get; set; }
    [Required]
    [DisplayName("Acronim")]
    public string Acronym { get; set; }
    [Required]
    [DisplayName("Numar contract")]
    public string ContractNo { get; set; }
    [Required]
    [DisplayName("Domeniu de activitate")]
    public virtual ActivityField ActivityField {get;set;}
    [Required]
    [DisplayName("Summary")]
    public string SummaryEn { get; set; }
    [Required]
    [DisplayName("Rezumat")]
    public string SumarryRo { get; set; }
    [Required]
    [DisplayName("Data inceput")]
    public virtual DateTime StartDate { get; set; }
    [Required]
    [DisplayName("Data sfarsit")]
    public virtual DateTime EndDate { get; set; }
    [Required]
    [DisplayName("Institutie coordonatoare")]
    public virtual string CoordInstitution { get; set; }
    [DisplayName("Valoare totala proiect")]
    public decimal TotalValue { get; set; }
    [DisplayName("Valuta")]
    public virtual Currency Currency { get; set; }
    [DisplayName("Rol in proiect")]
    public virtual RoleInProject RoleInProject { get; set; }//coord proiect/partener/in afara inst
    [DisplayName("Echipa proiect")]
    public virtual ICollection<Person> People { get; set; }
    [DisplayName("Director proiect")]
    public virtual Person ProjectManager { get; set; }
    public virtual ICollection<Institution> Partners { get;set;}
    public virtual Person PersonInCharge { get; set; }

    [DisplayName("Functie/Rol Expert In Proiect")]
    public string UserFunctionInProject { get; set; }
    [DisplayName("Pagina proiectului")]
    [Required]
    public string Website {get;set;}
    public virtual ICollection<Result> Results { get; set; }
}

当我遇到上一个问题时,它是一个类 Result 和同一个 Person 并且被告知如果我想要一个多对多关系我必须添加一个 Collection 到 Person 和一个 Collection 到 Result 并且这样做了把戏。

但是现在你可以看到我已经拥有了

public virtual ICollection<Person> People { get; set; } in Project

public virtual ICollection<Project> Projects { get; set; } in Person

每次我尝试向项目中添加多个用户时,我都会在从 DbContext 调用 Save() 方法时收到该标题中的错误

我不知道该怎么办。 谢谢。

不小心发错类,是结果而不是Person,现在正确了

更新 1

public void AddProjectForUsers(IEnumerable<int> userIds, Project project)
{
    foreach (var id in userIds)
    {
        AddProjectForUser(id,project);
    }
}

public void AddProjectForUser(int userId, Project project)
{
    var user = _ctx.Users.SingleOrDefault(u => u.Id == userId);
    if (user != null)
    {
        if (!user.Projects.Contains(project))
        {
            user.Projects.Add(project);
        }
    }
}

public bool Save()
{
    return _ctx.SaveChanges() > 0; // the error is thrown here
}

这 3 个来自我的存储库类

对他们的呼唤是

Repo.AddProjectForUsers(team, project);
Repo.Save();

其中团队是IEnumerable&lt;int&gt;,项目类型是Project

【问题讨论】:

  • 你这里有流畅的映射,还是你所有的映射都是用数据注解完成的?看起来 EF 认为您要添加的人是 ProjectManager 或 PersonInCharge。如果除了您已经提供的代码之外还有其他代码,请发布您的 O/R 映射代码。
  • @danludwig 没有流畅的映射,只是一些数据注释。
  • ... 而且您没有 PersonInCharge 或 ProjectManager 的任何外键属性... 将代码发布到引发异常的位置。另外,数据库中的外键是什么样的?你有3个,是吗?一个给 PM,一个给 PIC,另一个给项目动名词表?
  • @danludwig 用导致错误的函数更新了我的代码,我没有粘贴整个类和控制器。
  • 所以_ctx.UsersDbSet&lt;Person&gt;?另外,还是想看看你的 db FK。您有 3 个从 Project 到 Person 的关系,但从 Person 到 Project 只有 1 个关系,这可能是相关的。

标签: c# asp.net asp.net-mvc entity-framework


【解决方案1】:

看起来您可能需要 InverseProperty 数据注释属性来执行此操作:

namespace Prometheus.Models
{
    [Table("People")]
    public class Person : IPerson, INamedEntity
    {
        ...
        [InverseProperty("People")]
        public virtual ICollection<Project> Projects { get; set; }
    }
}

public class Project :INamedEntity
{
    ...
    [DisplayName("Echipa proiect")]
    [InverseProperty("Projects")]
    public virtual ICollection<Person> People { get; set; }
}

您收到的异常消息非常有说服力。由于 EF 抱怨该关系预计为一对零或一,这让我相信 EF 混淆了 People - Projects 关联与 PersonInCharge - Project 或 ProjectManager - Project 关联。

解决此问题的一种方法是在您的项目实体上公开外键属性,无论如何您都应该这样做 - 如果不这样做,您可能会遇到奇怪的瞬态错误。另一种方法是使用 fluent API(又名模型构建器)而不是数据注释。

【讨论】:

  • 非常感谢,它有效。你能告诉我你是从哪里学到的还是只是经验?
  • @toby 我刚刚搜索了“EF 多对多数据注释”,我认为这是第二个搜索结果。我从不使用数据注释,只使用 fluent API,所以不是经验。如果您使用流畅的映射 API,我会更快地回答您的问题。
猜你喜欢
  • 2013-03-30
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多