EntityFramework, получение идентификатора объекта при добавлении в таблицу

#c# #entity-framework #linq

#c# #entity-framework #linq

Вопрос:

У меня вопрос. Я добавляю объект в свою таблицу таким образом:

 this.db.Objects.Add(new Object { Text = "someText", Number = number });
 

Затем я хочу добавить второй объект в другую таблицу, которая связана с Objects таблицей (имя таблицы Objects3 ).

 this.db.Objects3.Add(new Object3 { ObjectId = ?, Property = "text" });
 

Как получить Object.Id (идентификатор в таблице — это int тип), основанный только на свойствах объекта?

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

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

    [ForeignKey("Object2")]
    public int Object2Id { get; set; }
    public Object2 Object2 { get; set; }

    public string Text { get; set; }
    public int Number { get; set; }

    public List<Object3> Objects3 { get; set; }
}

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

    [ForeignKey("Object")]
    public int ObjectId { get; set; }
    public Object Object { get; set; }

    public string Property { get; set; }
}
 

Комментарии:

1. Я не знаю, как это проверить? У меня просто есть класс DbContext, DbSets. Я делаю миграцию и обновление базы данных, не более того. Я полагаю, что это простой идентификатор автоматического увеличения, потому что, когда я добавляю что-то в базу данных (но из другой таблицы), оно уникально Id . Теперь я должен найти это Id из добавленного Object

2. Может быть, мы можем найти это Object (как object из списка) по их свойствам?

3. Попробуйте вызвать SaveChanges() после добавления первого объекта, и его Id столбец должен быть заполнен: var obj = new Object() {...}; this.db.Objects.Add(obj); this.db.SaveChanges(); var obj3 = new Object3() { ObjectId = obj.Id, ...};

4. Как я получу Object.Id , если я не инициализировал его сам, а AutoIncrement из базы данных sql?

5. хорошо, я попробую. Спасибо!

Ответ №1:

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

 var o1 = new Object() { ...
var o3 = new Object3() { ...

o3.Object = o1;

this.db.Objects3.Add( o3 );

this.db.SaveChanges();
 

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

Однако, если вы настаиваете на том, чтобы идентификатор был указан явным образом, вам следует сначала сохранить изменения, чтобы идентификатор был установлен в объекте

 var o1 = new Object() { ...
this.db.Objects.Add( o1 );

this.db.SaveChanges(); 

var id = o1.ID;
 

Теперь вы можете использовать свой идентификатор явным образом.

Побочное замечание — в ваших свойствах навигации отсутствует virtual модификатор, это сделает невозможным для EF замену реализации по умолчанию на реализацию с отложенной загрузкой для объектов, которые материализуются при выполнении запросов к базе данных.

 public class Object
{
    public Object()
    {
        this.Objects3 = new List<Object3>();
    }

    public virtual ICollection<Object3> Objects3 { get; set; }
}

public class Object3
{
    public virtual Object Object { get; set; }

}
 

Комментарии:

1. Спасибо! Но что, если я хочу перейти var o1 в другой класс? Как это o1.Id найти? возможно ли это или мне нужно Id как-то передать?

2. Что вы подразумеваете под «навигацией»?

3. Что делать, если я хочу найти это o1 в другом классе, потому что я проверил это, нет проблем получить правильное Id , как вы пишете в своем ответе в одном классе, но что, когда я добавлю o1 , как найти это o1.Id во втором классе?

4. Например, я добавляю o1 в class Class1 , затем я хочу каким-то образом получить o1.Id в Class2`методы

5. Используйте свойства навигации o2.Object.Id , предполагая, что вы сохраняете изменения в базе данных и идентификатор установлен.