Eu tenho esse erro nesta expressão linq:
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments
(
nalTmp.Dziecko.Imie,
nalTmp.Dziecko.Nazwisko,
nalTmp.Miesiace.Nazwa,
nalTmp.Kwota,
nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
nalTmp.DataRozliczenia,
nalTmp.TerminPlatnosci
)).ToList();
Alguma idéia de como resolver esse problema? Eu tento com qualquer combinação de expressão ...: /
c#
linq-to-entities
netmajor
fonte
fonte
Respostas:
sem mais informações sobre 'Pagamentos', isso não ajuda muito, mas suponha que você queira criar um objeto Pagamentos e definir algumas de suas propriedades com base nos valores da coluna:
fonte
Se você ainda deseja usar seu construtor para inicialização e não propriedades (às vezes esse comportamento é desejado para fins de inicialização), enumere a consulta chamando
ToList()
orToArray()
e, em seguida, useSelect(…)
. Assim, ele usará o LINQ to Collections e a limitação de não poder chamar o construtor com parâmetros inSelect(…)
desaparecerá.Portanto, seu código deve ser algo como isto:
fonte
ToX()
para isso, useAsEnumerable()
.Tendo acabado de encontrar esse erro, pensei em acrescentar que, se o
Payment
tipo for astruct
, você também encontrará o mesmo erro, porque osstruct
tipos não suportam construtores sem parâmetros.Nesse caso, a conversão
Payment
para uma classe e o uso da sintaxe do inicializador de objetos resolverão o problema.fonte
DateTime
(que é uma estrutura) dentro da minha consulta, que resulta no mesmo erro. extraí-lo para uma variável local corrigiu para mim. Obrigado pela dica struct.Se você é como eu e não deseja preencher suas propriedades para cada consulta que está criando, existe outra maneira de resolver esse problema.
Neste ponto, você tem um IQueryable contendo um objeto anônimo. Se você deseja preencher seu objeto personalizado com um construtor, basta fazer algo assim:
Agora, seu objeto personalizado (que aceita dois objetos como parâmetro) pode preencher suas propriedades conforme necessário.
fonte
Primeiro eu evitaria a solução com
Isso requer um construtor vazio e ignora o encapsulamento. Portanto, você está dizendo que novo Payments () é um pagamento válido sem dados, mas o objeto deve ter pelo menos um valor e provavelmente outros campos obrigatórios, dependendo do seu domínio.
É melhor ter um construtor para os campos obrigatórios, mas apenas trazer os dados necessários:
fonte
Você pode tentar fazer o mesmo, mas usando os métodos de extensão. Qual é o provedor do banco de dados usado?
fonte
Apenas
ToList()
oDbSet
antes daSelect
declaração .. o realDbSet
é guardada como uma consulta, não é ainda preenchidas. Após chamarToList()
você está jogando com objetos e, em seguida, você pode usar um construtor não padrão na consulta.Não é a maneira mais eficiente em termos de tempo de uso, mas é uma opção em aparelhos pequenos.
fonte
sim, tente assim ....
isso atualizará seu objeto Payment usando um construtor sem parâmetros e inicializará as propriedades listadas dentro dos chavetas
{ }
fonte
()
nos Payemnts não é necessário, por isso pode ser `selecionar novos Pagamentos {// valores de inicialização}Além dos métodos mencionados acima, você também pode analisá-lo como uma coleção Enumerable, assim:
Isso também tem o benefício adicional de facilitar a vida ao criar um objeto anônimo, como este:
Lembrando, no entanto, que a análise de uma coleção como Enumerable a armazena na memória, para que possa consumir muitos recursos! Cuidado deve ser usado aqui.
fonte
Além disso, se você desejar usar um construtor com vários objetos para inicializar, poderá receber um erro se nenhum valor for retornado pelo Linq.
Então, você pode querer fazer algo assim:
fonte
Desculpe por chegar atrasado à festa, mas depois de encontrar isso , achei que deveria ser compartilhado, pois é a implementação mais limpa, rápida e também de economia de memória que pude encontrar.
Adaptado ao seu exemplo, você escreveria:
As grandes vantagens aqui (como Damien Guard apontou nos comentários no link) são:
var foo = createPayments(bar);
possível usar o uso via myIQueryable.ToPayments ().fonte
Hoje eu tinha o mesmo problema e minha solução era semelhante à listada pela Yoda, no entanto, ela funciona apenas com sintaxe fluente.
Adaptando minha solução ao seu código: Adicionei o seguinte método estático à classe de objeto
e atualizou a consulta base para o seguinte:
Isso é logicamente equivalente à solução de James Manning, com a vantagem de empurrar o inchaço da inicialização do membro para o objeto de transferência de classe / dados
Nota: Originalmente, eu estava usando nomes mais descritivos que "Initializer", mas depois de revisar como o estava usando, descobri que "Initilizer" era suficiente (pelo menos para meus propósitos).
Nota final:
Depois de criar esta solução, eu originalmente pensava que seria simples compartilhar o mesmo código e adaptá-lo ao trabalho para a sintaxe de consulta também. Não acredito mais que seja esse o caso. Eu acho que se você quiser usar esse tipo de construção abreviada, precisará de um método para cada fluente (consulta, fluente), conforme descrito acima, que possa existir na própria classe de objeto.
Para a sintaxe da consulta, seria necessário um método de extensão (ou algum método fora da classe base). (como a sintaxe da consulta deseja operar um IQueryable em vez de T)
Aqui está um exemplo do que eu usei para finalmente fazer com que isso funcionasse para a sintaxe da consulta. (Yoda já acertou em cheio, mas acho que o uso pode ser mais claro porque não o compreendi a princípio)
e o uso
fonte
Embora seja tarde para responder, ainda pode ajudar alguém em perigo. Desde o LINQ para entidades, não há suporte para construções de objetos sem parâmetros. No entanto, os métodos de projeção para IEnumerable .
Portanto, antes da seleção, basta converter seu IQueryable para IEnumerable usando este código:
Vai funcionar bem. No entanto, é claro, perderá os benefícios das consultas nativas.
fonte
fonte