LINQ to SQL: Como posso encomendar por um objeto composto?
-
11-07-2019 - |
Pergunta
Eu tenho a seguinte consulta LINQ to SQL, no qual eu estou tentando fazer um GROUP multi-coluna:
return from revision in dataContext.Revisions
where revision.BranchID == sourceBranch.BranchID-1
&& !revision.HasBeenMerged
group revision by new Task(revision.TaskSourceCode.ToUpper(),
revision.TaskSourceID)
into grouping
orderby grouping.Key ascending
select (ITask)grouping.Key;
Isto lança InvalidOperationException ( "não pode ordenar por tipo 'Tarefa'.").
Existe uma interface que Task deve implementar (it já implementa IComparable, IComparable
Note que eu já tentei um tipo anônimo para o agrupamento, que falhou com um InvalidOperationException semelhante:
...
group revision by new { Code = revision.TaskSourceCode.ToUpper(),
Id = revision.TaskSourceID }
...
Por que vale a pena, nota que o objeto Task é um composto de 2 campos; um é um único caractere (normalmente 'S' ou 'B') eo outro é um int (na verdade um cross-database "chave estrangeira" se quiser). O ato de ordenação por Tarefas apenas compara suas representações de seqüência; POR EXEMPLO. Tarefa 'B101'
Solução
Parece que você já tem a sua solução, mas apenas FYI LINQ to SQL dá suporte .ToUpper()
.
Por exemplo:
NorthwindDataContext dc = new NorthwindDataContext();
Product product = dc.Products.Single(p => p.ProductName.ToUpper() == "CHAI");
é traduzido em:
exec sp_executesql N'SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
WHERE <b>UPPER([t0].[ProductName]) = @p0</b>',N'@p0 nvarchar(4)',@p0=N'CHAI'
Espero que ajude.
Outras dicas
OK, eu descobri isso. Eu tinha dois problemas; em primeiro lugar, ToUpper () não se traduz em SQL, e em segundo lugar, eu não acho Linq a suportes SQL orderBy em objetos; pelo menos não não-entidades. Ao se decompor o orderby em suas colunas constituintes, tudo começou a trabalhar como planejado.
return from revision in dataContext.Revisions
where revision.BranchID == sourceBranch.BranchID-1
&& !revision.HasBeenMerged
group revision by new { revision.TaskSourceCode,
revision.TaskSourceID }
into grouping
orderby grouping.Key.TaskSourceCode,
grouping.Key.TaskSourceID ascending
select (ITask)new Task(grouping.Key.TaskSourceCode,
grouping.Key.TaskSourceID);
Eu acho que você precisa de uma escolha antes de seu grupo por - você deseja converter objetos para Tarefas, em seguida, classificar por outra coisa (Task.start ou algo assim)
LINQ to SQL pode apoiar string.toupper (), mas não suporta Char.ToUpper (), que é o que eu precisaria para esta tabela e coluna particular. Mas obrigado pela informação de qualquer maneira!