C# 自引用类错误“;多重性在角色中无效…”;

C# 自引用类错误“;多重性在角色中无效…”;,c#,entity-framework,C#,Entity Framework,为了跟踪和声明web应用程序中的用户更改,我构建了一个类声明,应用程序的每个类都从中继承 索赔类引用用户类两次: 对创建记录的用户的引用 指最后修改记录数据的用户 用户类也从索赔类继承 我得到这个错误: User_LastChangedBy_Target::多重性在关系“User_LastChangedBy”中的角色“User_LastChangedBy_Target”中无效。因为依赖角色属性不是键属性,所以依赖角色的多重性上限必须为“*” 为了简化这个问题,我做了一个测试项目,其中有一个类用户

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

索赔类引用用户类两次:

  • 对创建记录的用户的引用
  • 指最后修改记录数据的用户
  • 用户类也从索赔类继承

    我得到这个错误:

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

    为了简化这个问题,我做了一个测试项目,其中有一个类用户引用自己两次

    如果我只使用一个自引用创建类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);
            }
        }
    }
    
    使用System.ComponentModel.DataAnnotations;
    使用System.ComponentModel.DataAnnotations.Schema;
    使用System.Data.Entity;
    名称空间测试
    {
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    MyContext db=新的MyContext();
    用户u=新用户();
    u、 Name=“约翰·多伊”;
    u、 IdCreate=1;
    u、 IdEdit=1;
    db.Users.Add(u);
    db.SaveChanges();
    }
    }
    [表(“测试用户”)]
    公共类用户
    {
    [关键]
    公共int Id{get;set;}
    公共字符串名称{get;set;}
    [外键(“CreatedBy”)]
    public int IdCreate{get;set;}
    公共用户CreatedBy{get;set;}
    [ForeignKey(“LastlyChangedBy”)]
    公共int-IdEdit{get;set;}
    公共用户LastlyChangedBy{get;set;}
    }
    公共类MyContext:DbContext
    {
    公共数据库集用户{get;set;}
    public MyContext():base(“数据源=192.168.5.2511433;用户ID=sa;pwd=XXXXXXX;初始目录=mywebapp”){
    //Database.SetInitializer(null);
    }
    }
    }
    
    有没有办法让它发挥作用?我在代码中犯了什么错误


    提前感谢

    您正在
    用户
    索赔
    之间使用TPT的概念,除非
    索赔
    是一个抽象类,并且不是在DB中生成的

    使您的代码能够毫无问题地工作。我建议您在
    声明
    用户
    之间创建一个连接表。因此,您的代码应该如下所示:

    索赔

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

    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;}
    }
    
    此类将保存
    UserId
    ClaimId
    ,以规范化的方式跟踪所有日志

    动作类型

    public enum ActionType
    {
         Added=1,
         Modified=2
    }
    
    这种结构将使您的数据更加规范和整洁


    希望这对您有所帮助

    您需要createdBy、lastchangedby的整个用户对象吗?如果是数据库,只需将用户名保存在字符串中,这可能是一个解决方法。最好将CreateBy和LastlyChangedBy标记为NotMapped并手动加载,但我认为我最初的想法应该可行,而且我确信有一个解决方案可以解决我的问题,但我不是EF专家。外键属性必须可以为空。否则,当没有可引用的用户时,无法插入用户。外键不得为空。您所指出的初始化问题只需创建两个内置用户“SYSTEM”自我引用和“Admin”引用“SYSTEM”即可解决。谢谢Monah。是的,索赔类是抽象的。我的型号是TPH。不要关注我的web应用程序,关注我提交的代码:“类用户必须引用自身两次”。如何做到这一点?