Можно ли перевести SQL-запрос в code-first linq-запрос для C# Entity Framework?
Есть следующий SQL-запрос:
select o.ID
, o.DigitalNumber
, isnull(sum(m.Quantity * case when r.StatusID != 3 then r.Time else 0 end) / 60.0, 0) AllSumm
from O o
left join M m on o.ID = m.OID
left join R r on m.ID = r.MID
where o.StatusID = 1 and m.StatusID != 3
group by o.ID
, o.DigitalNumber
order by o.ID desc;
Который далее через SqlConnection передаёт данные в C#:
var query = @"(код выше)";
using (var connection = ConnectionFactory.CreateDbConnection()) // SqlConnection
{
var items = connection.Query<OwithAdds>(query);
return items.ToList();
}
Хочу написать его версию на linq, чтобы эта версия смаппилась именно в sql-код выше (требуется высокая производительность). Есть ли такая возможность?
Версии: Net Framework 4.5.2, Entity Framework 6.3.0
Пробовал написать следующую версию, но она маппится в какой-то совсем уж монструозный многоуровневый sql-код (смотрел в Profiler), который работает очень долго (5s против 200ms):
return (from R in _rRepository.Table //IQueryable<R>
where (r.M.StatusID != 3)
group r by r.M.O
into g
where (g.Key.StatusID == 1)
orderby g.Key.ID descending
select new OwithAdds
{
ID = g.Key.ID,
DigitalNumber = g.Key.DigitalNumber,
AllSumm = g.Sum(x => x.StatusID != 3 ? x.Time * x.M.Quantity : 0) / 60.0 ?? 0
})
.ToList();
Классы в C# (сущности БД им полностью соответствуют) выглядят следующим образом:
public class O
{
public long ID { get; set; }
public long StatusID { get; set; }
public string DigitalNumber { get; set; }
public virtual ICollection<M> Ms
{
get { return _ms ?? (_ms = new List<M>()); }
protected set { _ms = value; }
}
private ICollection<M> _ms;
}
public class M
{
public long ID { get; set; }
public long StatusID { get; set; }
public long? Quantity { get; set; }
public long OID { get; set; }
public virtual O O { get; set; }
public virtual ICollection<R> Rs
{
get { return _rs ?? (_rs = new List<R>()); }
protected set { _rs = value; }
}
private ICollection<R> _rs;
}
public class R
{
public long ID { get; set; }
public long StatusID { get; set; }
public long? Time { get; set; }
public long MID { get; set; }
public virtual M M { get; set; }
}