Синтаксис LINQ lambda для подзапроса SQL count (отличается в одном столбце)

#linq #sql-server-2008 #c#-4.0

#linq #sql-server-2008 #c #-4.0

Вопрос:

Как бы я написал следующий SQL-запрос в LINQ с лямбда-нотацией?

 select 'myString', count(distinct val)
    from myChildTable
    where mytable_id in (
        select id
            from myTable
            where col1_int = 6
            and col2_int between 1 and 366
            and col3_str = 'myString'
        )
  

Для справки, две рассматриваемые таблицы:

 create table myTable (
id int primary key identity,
col1_int int not null,
col2_int int not null,
col3_str varchar(1024)
)

create table myChildTable (
id int primary key identity,
mytable_id int not null foreign key references myTable(id),
val varbinary(13) not null
)
  

Ответ №1:

Возможно, это можно было бы сократить, но я считаю, что его легче читать, если разбить:

 // list ids from table
var ids = myTable.Where(x => x.Col1Int == 6 amp;amp; x.Col2Int >= 1 amp;amp; x.Col2Int <= 366 amp;amp; x.Col3Str == "myString").Select(x => x.Id).ToList();

// use in subquery for values (non-distinct)
var vals = myChildTable.Where(x => ids.Contains(x.Id)).Select(x => x.Val).ToList();

// project to distinct dictionary of value, count
var dict = vals.Distinct().ToDictionary(x => x, x => vals.Count(y => y == x));
  

Похоже, это работает с использованием таких классов, как эти:

 class ParentEntity
{
    public int Id { get; set; }
    public int Col1Int { get; set; }
    public int Col2Int { get; set; }
    public string Col3Str { get; set; }

    public ParentEntity(int id, int col1Int, int col2Int, string col3Str)
    {
        Id = id;
        Col1Int = col1Int;
        Col2Int = col2Int;
        Col3Str = col3Str;
    }
}

class ChildEntity
{
    public int Id { get; set; }
    public int ParentEntityId { get; set; }
    public string Val { get; set; }

    public ChildEntity(int id, int parentEntityId, string val)
    {
        Id = id;
        ParentEntityId = parentEntityId;
        Val = val;
    }
}
  

Ответ №2:

Этот запрос должен к нему:

 from c in MyChildTables
where MyTables.Any (mt => mt.Col1_int == 6 amp;amp;  mt.Col2_int >= 1 amp;amp; 
      mt.Col2_int <= 366 amp;amp; mt.Col3_str == "myString" amp;amp; mt.Id == c.Id)
group c by true into g
select new
{
    Col1 = "myString",
    Col2 = g.Select (x => x.Val).Distinct().Count ()
}
  

Или, если вы предпочитаете использовать его в лямбда-нотации:

 MyChildTables
   .Where (
      c => 
         MyTables
            .Any (
               mt => 
                     (((((mt.Col1_int == 6) amp;amp; (mt.Col2_int >= 1)) amp;amp; (mt.Col2_int <= 366)) amp;amp; (mt.Col3_str == "myString")) amp;amp; (mt.Id == c.Id))
            )
   )
   .GroupBy (c => True)
   .Select (
      g => 
         new  
         {
            Col1 = "myString", 
            Col2 = g.Select (x => x.Val).Distinct ().Count ()
         }
   )