Entity Framework: могу ли я выполнить два отдельных запроса в одном запросе?

#c# #linq #entity-framework #asp.net-mvc-4

#c# #linq #entity-framework #asp.net-mvc-4

Вопрос:

Возможно ли выполнить два запроса к разным таблицам в одном запросе?

Например, если у меня есть этот DbContext:

 public DbSet<Farm> Farms { get; set; }
public DbSet<Farmer> Farmers { get; set; }
public DbSet<Llama> Llamas { get; set; }
 

И эти классы:

 public class Farm
{
    [Key]
    public Guid ID { get; set; }

    public virtual ICollection<Farmer> Farmers { get; set; }
    public virtual ICollection<Farmer> Llamas { get; set; }
}

public class Farmer
{
    [Key]
    public Guid ID { get; set; }
    public Guid FarmID { get; set; }

    public virtual Farm Farm { get; set; }
}

public class Llama
{
    [Key]
    public Guid ID { get; set; }
    public Guid FarmID { get; set; }

    public virtual Farm Farm { get; set; }
}
 

Можно ли было бы сделать эти два запроса в одном запросе?

 public IEnumerable<object> GetInhabitants(Guid farmID)
{
    DBContext db = new DBContext();

    IEnumerable<Farmer> farmers = db.Farmers.Where(x => x.FarmID == farmID);
    IEnumerable<Llama> llamas = db.Llamas.Where(x => x.FarmID == farmID);

    return [this would be easier if I could make one query]
}
 

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

1. Что именно он вернет? Класс FarmerLlama?

2. ManBearLlama? объект? Какой-то набор данных с фермерами и ламами? Или вы по сути говорите, что это невозможно?

3. Я думаю, вам следует применить MVVM в вашем случае. Создайте a ViewModel , который содержит свойства обоих Farmer и Llama класса, которые вы хотите отобразить в своем представлении

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

5. Поскольку ферма имеет навигационные свойства, не даст ли получение фермы с farmid доступ как к фермерам, так и к ламам?

Ответ №1:

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

 return db.Farmers.Where(x => x.FarmID == farmID)
       .Union(db.Llama.Where(x => x.FarmID == farmID));
 

(Примечание: я пишу это с головы до ног, поэтому синтаксис может быть немного неточным).

Отредактировано для добавления: возможно, вы захотите посмотреть отложенное выполнение. Если вы используете объект IQueryable, вы можете сделать в коде столько запросов Entity Framework, сколько захотите, но фактически они не будут выполняться, пока вы не запустите выполнение (обычно путем вызова .ToList()) .

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

1. У фермеров и лам нет общего базового класса. Вы не можете объединить их таким образом, если не спроецируете их оба на анонимный объект с одинаковыми свойствами.

2. Суть ответа верна, даже если синтаксис не совсем правильный (о чем я прямо сказал). OP спрашивал, возможно ли объединить 2 запроса LINQ в один запрос. Объединение — один из подходов к этому.