实体框架正在尝试插入错误的表中?

时间:2018-10-16 13:37:16

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

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

我希望数据库存储用户的ID,并且在检索用户ID(“ AcceptedFriends”)时,我希望实体框架也返回朋友“ usermodel”。

但是每次我尝试将2个用户作为朋友添加到“ AcceptedFriends”表中时, 引发异常:

违反了PRIMARY KEY约束'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

在这里我添加朋友/用户

另外,当我将新用户添加到friends表时,我注意到了另一个奇怪的行为  无需先将它们添加到users表中,而是将它们同时添加到friends表和users表中。

        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

我可能已经找到了解决方案。 确实会为用户和朋友返回模型, 但是我还不能接受这作为解决方案,因为感觉对我来说是hackey(?)

(感谢@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;
        };
    }

1 个答案:

答案 0 :(得分:0)

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

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

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