【问题标题】:Self referencing class error "Multiplicity is not valid in Role ..."自引用类错误“多重性在角色中无效......”
【发布时间】:2019-10-26 12:24:04
【问题描述】:

为了在我的 Web 应用程序中跟踪和声明用户更改,我构建了一个类 Claim,应用程序的每个类都从该类继承。

Claim 类两次引用 User 类:

  1. 对创建记录的用户的引用
  2. 对上次修改记录数据的用户的引用

User 类也继承自 Claim 类。

我收到此错误:

User_LastChangedBy_Target: : 多重性在关系“User_LastChangedBy”中的角色“User_LastChangedBy_Target”中无效。因为依赖角色属性不是关键属性,所以依赖角色的多重性的上限必须是'*'

为了简化问题,我做了一个测试项目,它有一个类 User 两次引用自己。

如果我只使用一个自引用创建类 User,它就可以工作。

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;

namespace TestEF
{
    class Program
    {
        static void Main(string[] args)
        {
            MyContext db = new MyContext();

            User u = new User();
            u.Name = "John Doe";
            u.IdCreate = 1;
            u.IdEdit = 1;

            db.Users.Add(u);

            db.SaveChanges();
        }
    }

    [Table("test_users")]
    public class User
    {
        [Key]
        public int Id { get; set; }

        public string Name { get; set; }

        [ForeignKey("CreatedBy")]
        public int IdCreate { get; set; }
        public User CreatedBy { get; set; }

        [ForeignKey("LastlyChangedBy")]
        public int IdEdit { get; set; }
        public User LastlyChangedBy { get; set; }
    }

    public class MyContext : DbContext
    {
        public DbSet<User> Users { get; set; }

        public MyContext() : base("Data Source=192.168.5.251,1433;User ID=sa;pwd=XXXXXXX;Initial Catalog=mywebapp") {
            //Database.SetInitializer<MyContext>(null);
        }
    }
}

有没有办法让它工作?我的代码有什么错误?

提前致谢

【问题讨论】:

  • 你需要整个用户对象来创建createdby,lastchangedby吗?如果它用于数据库,只需将用户名保存在字符串中
  • 这可能是一种解决方法。更好的是可以将 CreateBy 和 LastlyChangedBy 标记为 NotMapped 并手动加载它们,但我认为我最初的想法应该可行,而且我确信我的问题有解决方案,但我不是 EF 大师。
  • 外键属性必须可以为空。否则在没有用户可引用的情况下,您无法插入用户。
  • 外键不能为空。您指出的初始化问题只是简单地解决了创建两个内置用户“SYSTEM”自引用和“Admin”引用“SYSTEM”。

标签: c# entity-framework


【解决方案1】:

您在UserClaim 之间使用TPT 的概念,除非Claim 是一个抽象类并且不在数据库中生成。

让您的代码正常工作。我敦促您在ClaimsUsers 之间创建一个联结表。所以,您的代码应该如下所示:

声明

public class Claim
{
     // your code goes here
}

用户

public class User: Claim
{
      // your code goes here
}

用户操作

public class UserAction
{ 
       public int Id{get;set;}
       public int UserId{get;set;}
       public int ClaimId{get;set;}
       public DateTime CreatedOn{get;set;}
       public ActionType Action{get;set;}

       public User User{get; set;}
       public Claim Claim{get;set;}
}

该类将保存UserIdClaimId 以标准化方式跟踪所有日志。

动作类型

public enum ActionType
{
     Added=1,
     Modified=2
}

这种结构将使您的数据更加规范和整洁。

希望对你有帮助

【讨论】:

  • 谢谢莫娜。是的,Claim 类是抽象的。我的型号是TPH。不要专注于我的网络应用程序,专注于我提交的代码:“类用户必须引用自身两次”。如何实现?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多