#c# #.net #entity-framework
#c# #.net #entity-framework
Вопрос:
У меня есть этот класс модели:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<User> Collection1 { get; set; } = new List<User>();
public virtual ICollection<User> Collection2 { get; set; } = new List<User>();
}
Затем я добавляю несколько записей в базу данных:
var context = new UsersContext();
var user1 = new User();
var user2 = new User();
var user3 = new User();
user1.Name = "user1";
user2.Name = "user2";
user3.Name = "user3";
user1.Collection1.Add(user2);
user2.Collection1.Add(user3);
context.Users.Add(user1);
context.Users.Add(user2);
context.Users.Add(user3);
context.SaveChanges();
Затем я запускаю этот запрос:
var user2 = context.Users.First(user => user.Name == "user2");
foreach (var u in user2.Collection2)
Console.WriteLine($"{user2.Name} Collection2 {u.Name}");
И я получаю:
пользователь2 Коллекция2 пользователь1
Почему Collection2
у меня есть запись? И как это исправить?
Обновить.
Это ссылка на тестовый проект https://drive.google.com/file/d/0BxP-1gZwSGL5S1c4cWN1Q2NsYVU/view
Комментарии:
1. Вопрос не ясен. Вы имеете в виду, почему существует запись или почему запись ‘user1’?
2. На самом деле интересное поведение. Похоже, у EF есть
many-to-many
отношение настройки для вас. Вы можете убедиться в этом, просмотрев сгенерированные таблицы.3. @peval27, извините за мой английский. Почему в collection2 есть запись? Я его не добавлял.
4. @Lightness Я считаю, что объявление его как виртуальной коллекции означает неявную ссылку на таблицу пользователей с именем Collection2. Проверьте таблицы, созданные в БД
5. Пожалуйста, посмотрите на мой проект. Вы увидите, в чем проблема. drive.google.com/file/d/0BxP-1gZwSGL5S1c4cWN1Q2NsYVU /…
Ответ №1:
Это не странно, а ожидаемое поведение.
Рассмотрим следующую модель:
public class Entity1
{
public int Id { get; set; }
public ICollection<Entity2> Collection2 { get; set; }
}
public class Entity2
{
public int Id { get; set; }
public ICollection<Entity1> Collection1 { get; set; }
}
Это типичная many-to-many
связь EF с неявной таблицей соединений. Когда вы добавляете entity1
to entity2.Collection1
, он также добавляет entity2
to entity1.Collection2
.
Теперь замените Entity1 = Entity2 = User
. Результатом является именно ваша модель.
Вкратце, с помощью этой модели EF создает собственные many-to-many
отношения через неявную UsersUsers
таблицу соединений, вот почему вы получаете описанное поведение.
Поскольку ваше намерение, похоже, имеет два one-to-many
отношения, вам нужно явно сообщить об этом EF, используя Fluent API:
public class UsersContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasMany(e => e.Collection1).WithOptional();
modelBuilder.Entity<User>().HasMany(e => e.Collection2).WithOptional();
}
}
Теперь все будет работать так, как ожидалось.
Комментарии:
1. Отличное объяснение 1 🙂