score:3

Accepted answer

If you use the query syntax, you can declare variables.

This is how your query would look like in query syntax (please name your variables properly. I don't know what you are actually doing so I can't name them...):

var query = from a in UoW.Repository
    .Get(echangeFilter)
    group a by new
    {
        Id = MyBLL.IsInComing(a.idSens) ? MyBLL.FindByNoContactModel(a.change.idTo.GetValueOrDefault()).id : MyBLL.FindByNoContactModel(a.change.idFrom.GetValueOrDefault()).id,
        Tri = MyBLL.IsInComing(a.idSens) ? MyBLL.FindByNoContactModel(a.change.idTo.GetValueOrDefault()).Tri: MyBLL.FindByNoContactModel(a.change.idFrom.GetValueOrDefault()).Tri,
        SensAppel = a.echange_sens.nom
    } into g
    let b = new
    {
        group.Key.Id, 
        group.Key.Tri,
        Count = group.Count(),
    }
    orderby g.Tri
    select g;
var stats = query.ToList();

Now we can introduce a let:

var query = from a in UoW.Repository
    .Get(echangeFilter)
    let x = MyBLL.IsInComing(a.idSens) ? MyBLL.FindByNoContactModel(a.change.idTo.GetValueOrDefault()) : MyBLL.FindByNoContactModel(a.change.idFrom.GetValueOrDefault())
    group a by new
    {
        Id = x.id,
        Tri = x.Tri,
        SensAppel = a.echange_sens.nom
    } into g
    let b = new
    {
        g.Key.Id, 
        g.Key.Tri,
        Count = g.Count(),
    }
    orderby g.Tri
    select g;
var stats = query.ToList();

score:0

This works by first returning whatever model FindByNoContactModel returns per record and SensAppel, so you only have to call the IsIncoming and FindByNoContactModel once per row. Depending on how many rows you expect to be returned, you may find very quickly that you are better off pushing these lookups elsewhere, or letting the database do it.

var stats = UoW.Repository
    .Get(echangeFilter)
    .Select(a=> new {
        Model = MyBLL.IsIncoming(a.idSens)
          ? MyBLL.FindByNoContactModel(a.change.idTo.GetValueOrDefault()) 
          : MyBLL.FindByNoContactModel(a.change.idFrom.GetValueOrDefault()),
        SensAppel = a.echange_sens.nom 
    })
    .GroupBy(a => new
    {
        Id = a.Model.id,
        Tri = a.Model.Tri,
        SensAppel = a.SensAppel
    })
    .Select(group => new
    {
        group.Key.Id, 
        group.Key.Tri,
        group.Key.SensAppel,
        Count = group.Count(),
    })
    .OrderBy(g => g.Tri)
    .ToList();

score:0

Is this what you're looking for?

var stats = UoW.Repository
.GroupBy(a => {
    var repo = MyBLL.IsInComing(a.idSens) ? MyBLL.FindByNoContactModel(a.change.idTo.GetValueOrDefault()) : MyBLL.FindByNoContactModel(a.change.idFrom.GetValueOrDefault())

    return new
    {
        Id = repo.id,
        Tri = repo.Tri,
        SensAppel = a.echange_sens.nom
    }

})
.Select(group => new
{
    group.Key.Id, 
    group.Key.Tri,
    Count = group.Count(),
})
.OrderBy(g => g.Tri)
.ToList();

score:-1

You can combine the sub-expressions by pulling out the common elements and then using an intermediate anonymous class to hold them (I am not sure how EF 6 will handle this (what does Get return?) as I don't know what MyBLL is):

var stats = UoW.Repository
    .Get(echangeFilter)
    .Select(a => new {
        a.echange_sens.nom,
        fncm = MyBLL.FindByNoContactModel(
                   (MyBLL.IsInComing(a.idSens)
                       ? a.change.idTo
                       : a.change.idFrom)
                   .GetValueOrDefault())
    })
    .GroupBy(nf => new {
        Id = nf.fncm.id,
        Tri = nf.fncm.Tri,
        SensAppel = nf.nom
    })
    .Select(group => new {
        group.Key.Id,
        group.Key.Tri,
        Count = group.Count(),
    })
    .OrderBy(g => g.Tri)
    .ToList();

Related Articles