【问题标题】:Entity Framework is trying to insert into wrong table?实体框架试图插入错误的表?
【发布时间】:2019-03-21 01:33:36
【问题描述】:

我已经使用 Entity Framework 构建了一个测试应用程序来模拟包含好友列表的数据库。

我希望数据库存储用户的 ID,当我检索它们时(“AcceptedFriends”),我希望 Entity Framework 也返回朋友“usermodel”。

但每次我尝试将 2 个用户作为朋友添加到“AcceptedFriends”表时 抛出异常:

" 违反主键约束“PK_Users”。无法在对象“dbo.Users”中插入重复键。重复键值为(用户 ID 的 GUID 值)

一些尝试的解决方案:

  1. Solution 1

  2. 尝试创建 2 个相同朋友列表的列表(已接收、已发送),但这违背了我想要达到的目的。

  3. Solution 2

这里是代码文件:

“用户模型”

 public class Users
 {

    #region Private fields

    #endregion


    #region Public properties

    public string Username { get; set; }

    public string ID { get; set; }

    public string PasswordHash { get; set; }


    public virtual List<AcceptedFriends> AcceptedFriendsList { get; set; }

    // public virtual List<PendingFriends> PendingFriendsList { get; set; }

    // public virtual  List<RemovedFriends> RemovedFriendsList { get; set; }

    #endregion
}

“接受好友模型”

    public class AcceptedFriends
    {
        #region Public properties

        public string RelationKey { get; set; }

        public string RequestSenderID { get; set; }

        public string RequestReceiverID { get; set; }


        public virtual List<Messages> ChatList { get; set; }


        public Users RequestSender { get; set; }

        public Users RequestReceiver { get; set; }

        #endregion
     }

“数据库模型创建”

        #region Users table

        // Create primary key in Users table
        modelBuilder.Entity<Users>().HasKey(property => property.ID);

        // Map Username to be unique
        modelBuilder.Entity<Users>().HasIndex(property => property.Username).IsUnique();

        // Create a one to many relation with AcceptedFriends table
        modelBuilder.Entity<Users>()
            .HasMany(property => property.AcceptedFriendsList)
            .WithOne(property => property.RequestReceiver)
            .HasForeignKey(property => property.RequestReceiverID);


        #endregion


        #region Accepted friends table

        // Create key for AcceptedFriends
        modelBuilder.Entity<AcceptedFriends>().HasKey(property => property.RelationKey);

        #endregion

编辑

这是我插入朋友的方式

public static void AddFriends(AcceptedFriends friends)
{
    using(Context context = ConnectToDatabase())
    {
        context.AcceptedFriends.Add(friends);

        context.SaveChanges();
    };
 }

编辑 2

这里是我添加朋友/用户的地方

另外,当我将新用户添加到好友表时,我发现了另一个奇怪的行为 在不先将它们添加到用户表的情况下,它会将它们同时添加到朋友表和用户表中。

        Console.WriteLine("Connecting to database");

        DB.ConnectToDatabase();
        Console.WriteLine("Connected to database successfully");

        List<Users> userList = new List<Users>(DB.GetUsersList());

        List<AcceptedFriends> friendsCount = new List<AcceptedFriends>(DB.GetAcceptedFriends());


        if(userList.Count != 2)
        {
            DB.AddUser(new Users()
            {
                Username = "User1",
                PasswordHash = "PasswordHash",
            });

            DB.AddUser(new Users()
            {
                Username = "User2",
                PasswordHash = "PasswordHash",
            });

            userList = new List<Users>(DB.GetUsersList());
        };


        if(friendsCount.Count < 1)
        {
            Users user1 = userList[0];
            Users user2 = userList[1];

            DB.AddFriends(new AcceptedFriends()
            {
                RequestReceiver = user2,

                RequestSender = user1,
            });
        };

        Console.WriteLine("Server is great success!");

        Console.ReadLine();

编辑 3

我可能已经找到了解决方案。 它确实为用户和朋友返回模型, 但我还不能接受这是一个解决方案,因为我觉得这很糟糕(?)

(感谢@wertzui,您帮助我找到了这个解决方案)

基本上每次创建新上下文时,它都会设置朋友和用户返回他们的用户模型

/// <summary>
    /// Gets the friends user models
    /// </summary>
    /// <param name="context"> The database context that was created </param>
    private static void SetupFriends(Context context)
    {
        // For every "AcceptedFriend"
        foreach(AcceptedFriends friend in context.AcceptedFriends)
        {
            // Get sender and receiver usermodels 
            // by matching ID's
            Users sender = context.Users.FirstOrDefault(user => user.ID == friend.RequestSenderID);
            Users receiver = context.Users.FirstOrDefault(user => user.ID == friend.RequestReceiverID);

            sender.AcceptedFriendsList.Add(friend);
            receiver.AcceptedFriendsList.Add(friend);

            friend.RequestSender = sender;
            friend.RequestReceiver = receiver;
        };
    }

【问题讨论】:

  • 请分享您的friends-variable 是如何创建/填充的
  • 已添加。请再看看
  • 现在才明白你的意思。 friends是我用来传递朋友模型的参数

标签: c# sql .net entity-framework entity-framework-core


【解决方案1】:

当您在 new AcceptFriends {...} 代码中创建新用户实例时,您没有设置它们的 Id,因此它们保持默认值 0。现在 Entity Framework 认为,您想与 2 个新用户创建一个新的友谊。相反,您应该使用之前创建的用户来填充它们。

if(friendsCount.Count < 1)
{
    Users user1 = userList[0];
    Users user2 = userList[1];

    DB.AddFriends(new AcceptedFriends()
    {
        RequestReceiver = user1,
        RequestSender = user2,
    });
}

【讨论】:

  • 很好的建议,但没有奏效,顺便说一句,经过进一步测试,实体框架是否会自动添加 ID。我尝试将用户与朋友表映射的方式可能存在“错误”吗?
  • 尝试设置 RequestReceiverId 和 RequestSenderId 而不是对象。
  • 已尝试。是的,它添加了它们,但是它违背了我想要实现的目的,因为它没有加载“朋友”“用户”模型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多