Я создал тестовое приложение с Entity Framework для имитации базы данных, содержащей списки друзей.
Я хочу, чтобы база данных хранила идентификатор пользователя, и когда я их извлекаю ("AcceptedFriends"), я хочу, чтобы Entity Framework также возвращала друзьям "usermodel".
Но каждый раз, когда я пытаюсь добавить 2 друзей в качестве друзей в таблицу "AcceptedFriends", он выдает исключение:
" Нарушение ограничения PRIMARY KEY" PK_Users ". Невозможно вставить дублирующий ключ в объект" dbo.Users ". Значение дублирующегося ключа (значение GUID идентификатора пользователя) "
Некоторые попытки решения:
Попытка создать 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
Здесь я добавляю друзей/пользователей
Плюс я заметил еще одно странное поведение. Когда я добавляю новых пользователей в таблицу друзей, не добавляя их сначала в таблицу 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
Я мог бы найти решение. Он возвращает модели как для пользователя, так и для друзей, но я не могу принять это как решение еще, потому что он чувствует себя взломанным (?) Для меня
(Благодаря @wertzui, вы помогли мне добраться до этого решения)
В основном каждый раз, когда создается новый контекст, он настраивает друзей и пользователей, чтобы вернуть их usermodels
/// <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;
};
}
Когда вы создаете новые пользовательские экземпляры в вашем new AcceptFriends {...}
, вы не устанавливаете свой Id
, поэтому они сохраняют свое значение по умолчанию, new AcceptFriends {...}
0
. Теперь Entity Framework думает, что вы хотите создать новую дружбу с двумя новыми пользователями. Вместо этого вы должны заполнить их пользователями, которые вы создали ранее.
if(friendsCount.Count < 1)
{
Users user1 = userList[0];
Users user2 = userList[1];
DB.AddFriends(new AcceptedFriends()
{
RequestReceiver = user1,
RequestSender = user2,
});
}
friends
переменная создается / заполняется