#c# #entity-framework-6
#c# #entity-framework-6
Вопрос:
Я пытаюсь «сохранить» ссылку на родительский элемент в объекте после запроса к EF, запускаемого родительским объектом, при фильтрации как родительского, так и дочерних элементов и возврате дочерних элементов. Но те дочерние записи, которые я возвращаю, должны поддерживать свою ссылку на родительский элемент.
В приведенном ниже примере родительский элемент доступен «до тех пор, пока не будет выполнен выбор», а затем дочерние элементы будут возвращены… но ссылка «назад» на родительский элемент теряется. КАК я могу не потерять этот объект родительского элемента???
итак, что мне нужно, так это то, что возвращаемый результат Table2Model по-прежнему содержит ссылку на родительский элемент в МОДЕЛИ .. но после оператора select эта ссылка теряется.
если я добавлю это
result.ForEach((t2) =>
{
t2.Table1 = db.Table1Model.SingleOrDefault(t1 => t1.Table1Id == t2.Table1Id);
});
это устраняет мою проблему… но мне было интересно, есть ли какой-нибудь способ сохранить родительскую ссылку в исходном вызове. Выполнение этого в два этапа удваивает трудоемкость запроса.
(ниже приведен контекст базы данных)
public class Table1Model {
public Table1Id {get; set;}
public Name {get; set;}
public Desc {get; set;}
public virtual ICollection<Table2Model> Table2Models {get; set;}
}
public class Table2Model {
public Table2ModelId {get; set;}
public SpecialData1 {get; set;}
public SpecialData2 {get; set;}
public SpecialData3 {get; set;}
public Table1Id {get; set;}
public virtual Table1Model Table1 {get; set;}
}
public class List<Table2Model> DoWork(sampleRequest request){
var result = db.Table1Model
.Where(t => t.Name = request.Name)
.Select(t => t.Table2Models.OrderByDescending(n => n.Table2ModelId).FirstOrDefault())
.OrderBy(t2 => t2.SpecialData1)
.Take(5)
.ToList();
return resu<
}
Комментарии:
1. Есть ли в вашей
Table2Model
таблице в базе данныхTable1Id
столбец? Если вы просто ссылаетесь на это свойство, оно должно лениво загрузить родительский объект. В качестве альтернативы вы могли бы один раз извлечь этот родительский элемент из базы данных и вручную назначить его всем дочерним элементам.2. да, это так .. я просто исправил это выше
3. если я нарушу запрос… загружаются ссылки .. все указывают друг на друга… НО как только выполняется запрос select, и проецируются table2models… по какой-то причине он теряет указатели на родительский элемент. (Свойство Table1 для Table2Model равно null)
4. Все, что проецирует запрос (
Select
,GroupBy
и т.д.), Приведет к потере «Включает». Иногда вы можете использоватьInclude
после проекции, если вы проецируете на настроенный объект.5. Я понимаю.. тогда нет способа сохранить его? … ах .. ок .. дай мне попробовать.. о чем упоминал Брэдли.
Ответ №1:
Возможно, я здесь чего-то не хватает, но почему бы не спроецировать в другую модель и включить обе части.
public class TheModel
{
public Table1Model Table1Model { get; set; }
public Table2Model Table2Model { get; set; }
}
var result = db.Table1Model
.Where(t => t.Name = request.Name)
.Select(t => new TheModel {
Table1Model = t,
Table2Model = t.Table2Models
.OrderByDescending(n => n.Table2ModelId)
.FirstOrDefault())
.OrderBy(t2 => t2.Table2Model.SpecialData1)
.Take(5)
.ToList();
На самом деле я бы посоветовал вам разбить TheModel
только на конкретные свойства, которые вам нужны, и быть немного более детализированным с запросом, но я не знаю, что именно вам нужно, не могу привести более конкретный пример.
Комментарии:
1. Я решил это, используя предложение @BradleyUffner… я пробовал это раньше, но, должно быть, сделал что-то не так.. теперь он работает с включением «после» проекции выбора.