Подтвердить что ты не робот

Entity Framework создает объекты внешнего ключа вместо использования уже доступных

мой текущий проект основан на первом коде Entity Framwork. У меня есть три типа: Task, TaskType и Module.

    public class Task
    {
        public int ID { get; set; }
        public Module Module { get; set; }
        public TaskType Type { get; set; }
    }

    public class TaskType
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class Module
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

В таблице заданы отношения внешних ключей, определенные в таблице Task.

Моя проблема в том, что когда я пытаюсь создать новый объект Task, связанный с уже доступными объектами TaskType и Module (ID = 1), эти объекты создаются в виде новых строк в соответствующих таблицах.

        TaskRepository repo = new TaskRepository();

        Task task = new Task();
        task.Module = Modules.SingleOrDefault(m => m.ID == 1);
        task.Type = TaskTypes.SingleOrDefault(t => t.ID == 1);

        Tasks.Add(task);

Это создает новую строку в моей таблице TaskType и в моей таблице Modules вместо того, чтобы просто использовать уже доступный идентификатор TaskType-ID и ID модуля.

Надеюсь, я ясно дал понять, что моя проблема: -)

Заранее благодарим за помощь. Я ценю это.

С уважением, Кевин

4b9b3361

Ответ 1

Если вы не используете один и тот же экземпляр контекста для загрузки связанных объектов, вы не можете просто добавить их в новый объект и ожидать, что существующие записи в базе данных будут использоваться. Новый контекст не знает, что эти экземпляры существуют в базе данных - вы должны сказать это в контексте.

Решения:

  • Использовать тот же контекст как для связанных с загрузкой объектов, так и для сохранения нового объекта
  • Не загружать связанные объекты и использовать фиктивные объекты
  • Загружает объекты из первого контекста и отделяет их, присоединяет объекты к новому контексту и после этого назначает их новому объекту.
  • После добавления нового объекта с отношениями вручную измените состояние отношений от Added до Unchanged

Пример для 1:

var module = context.Modules.SingleOrDefault(m => m.ID == 1);
var taskType = context.TaskTypes.SingleOrDefault(t => t.ID == 1);

Task task = new Task();
task.Module = module;
task.Type = taskType;

context.Tasks.Add(task);

Пример для 2:

var module = new Module { Id = 1 };
var taskType = new TaskType { Id = 1 };

context.Modules.Attach(module);
context.TaskTypes.Attach(taskType);

Task task = new Task();
task.Module = module;
task.Type = taskType;

context.Tasks.Add(task);

Пример для 3:

var module = otherContext.Modules.SingleOrDefault(m => m.ID == 1);
otherContext.Entry(module).State = EntityState.Detached;

var taskType = otherContext.TaskTypes.SingleOrDefault(t => t.ID == 1);
otherContext.Entry(taskType).State = EntityState.Detached;

context.Modules.Attach(module);
context.TaskTypes.Attach(taskType);

Task task = new Task();
task.Module = module;
task.Type = taskType;

context.Tasks.Add(task);

Пример для 4:

var module = otherContext.Modules.SingleOrDefault(m => m.ID == 1);
otherContext.Entry(module).State = EntityState.Detached;

var taskType = otherContext.TaskTypes.SingleOrDefault(t => t.ID == 1);
otherContext.Entry(taskType).State = EntityState.Detached;

Task task = new Task();
task.Module = module;
task.Type = taskType;

context.Tasks.Add(task);

context.Entry(module).State = EntityState.Unchanged;
context.Entry(taskType).State = EntityState.Unchanged;

Ответ 2

Я новичок в инфраструктуре сущности, но я просто столкнулся с той же проблемой, где было добавлено мое свойство внешнего ключа, но объект навигации был пустым, с кодом вроде:

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


    public int EntryRecordId { get; set; }

    [ForeignKey("EntryRecordId")]
    public EntryRecord EntryRecord { get; set;}

}

Настройка свойства навигации для виртуальной системы устраняет проблему и обеспечивает ленивую загрузку:

    [ForeignKey("EntryRecordId")]
    public virtual EntryRecord EntryRecord { get; set;}