Entity Framework Code «Сначала многие ко многим», создающий дублирующиеся строки - PullRequest
8 голосов
/ 13 ноября 2010

У моей проблемы оказалось два контекста.Я немного переработал свой код, чтобы иметь только один контекст, и моя проблема исчезла.

У меня есть Пользователь, у которого есть список UserContact, который сам имеет ContactOption.Это довольно просто 1 ко многим, многие к 1 с таблицей UserContact в середине.

Если я вытащу пользователя из БД и создам новый UserContact, но установлю для ContactOption существующий элемент (которыйЯ вытащил из базы данных), когда я SaveChanges, структура сущностей создает новый ContactOption в базе данных, который по сути является дубликатом того, который я добавил в UserContact (за исключением того, что он получает новый идентификатор).

Я боролся с этим в течение нескольких часов и не могу понять это.Любые идеи?

Я использую шаблон Repository для своих запросов к базе данных, но я убедился, что они используют один и тот же контекст.

Я вытаскиваю пользователя из базы данных следующим образом:

var user = _context.Users.Include("UserContacts.ContactOption")
              .Where(id => id == 1);

И параметры контакта извлекаются с помощью:

var co = _context.ContactOptions.FirstOrDefault(c => c.Id == id);

И я добавляю ContactOption к UserContact так:

var contactOption = _context.ContactOptions.FirstOrDefault(c => c.Id == someId);

var contact = new UserContact { ContactOption = contactOption  };
contact.Data = "someData";

user.UserContacts.Add(contact);

Моя модель выглядит следующим образом:

public class User
{
    [Key]
    public int Id { get; set; }

    public virtual ICollection<UserContact> UserContacts { get; set; }
}

public class UserContact
{
    [Key]
    public int Id { get; set; }

    [Required]
    public User User { get; set; }

    [Required]
    public ContactOption ContactOption { get; set; }
    public string Data { get; set; }
}

public class ContactOption
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}

Ответы [ 2 ]

2 голосов
/ 14 ноября 2010

Я запустил ваш код и получил точные ожидаемые результаты: Новая строка в таблице UserContacts с существующими UserId и ContactOptionId, поэтому я не уверен, что там происходит, но вы можете попытаться явноФК в объекте UserContact, чтобы вы имели полный контроль над тем, как Code First вставляет записи для вас.Для этого вам нужно изменить UserContact следующим образом:

public class UserContact
{
    public int Id { get; set; }

    // By Convention these 2 properties will be picked up as the FKs: 
    public int UserId { get; set; }
    public int ContactOptionId { get; set; }

    [Required]
    public User User { get; set; }        
    [Required]
    public ContactOption ContactOption { get; set; }

    public string Data { get; set; }
}

И тогда вы можете изменить свой код следующим образом:

var contactOption = _context.ContactOptions.Find(someId);
var user = _context.Users.Find(1);

var contact = new UserContact 
{ 
    ContactOptionId = contactOption.Id,  
    UserId = user.Id,
    Data = "someData"
};

user.UserContacts.Add(contact);
context.SaveChanges();
1 голос
/ 14 ноября 2010

У моей проблемы оказалось два контекста.Я немного переработал свой код, чтобы иметь только один контекст, и моя проблема ушла.Спасибо Мортезе Манави за то, что он указал мне правильное направление.

...