Where clause after String.Join in Linq to Entites - c#

I have a Linq to Entites query where I have implemented the logic. But, I have done the query where clause performs after string join. BTW, I need to know how can I join the string first before doing the where filter. When I execute the query where clause after the string join, it takes so long to filter the records. Since my database have nearly 2 lakh sample records.
Here is my query what I am looking for:
// But the below query throws string join cannot be converted to store expression.
var NewBibContentsModel = (from x in db.BibContents
where (x.TagNo == "245" && string.Join(" ", x.NormValue) == aa.CurrentTitle) || ((x.TagNo == "020") || (x.TagNo == "022") && string.Join(" ", x.NormValue) == aa.CurrentISBN)
select new
{
BibId = x.BibId,
Title = (from a in db.BibContents where a.BibId == x.BibId && a.TagNo == "245" orderby a.Id ascending select a.NormValue),
Author = (from a in db.BibContents where a.BibId == x.BibId && splitted.Contains(a.TagNo) && a.NormValue != null select a.TagNo).FirstOrDefault(),
ISBN = (from a in db.BibContents where a.BibId == x.BibId && a.NormValue != null && (a.TagNo == "020" || a.TagNo == "022") orderby a.Id ascending select a.NormValue)
}).AsEnumerable().Select(x => new BibContentsModel
{
BibId = x.BibId,
Title = string.Join(" ", x.Title),
Author = string.Join(" ", (from a in db.BibContents where a.BibId == x.BibId && a.TagNo == x.Author orderby a.Id select a.NormValue)),
ISBN = string.Join(" ", x.ISBN),
RRId = aa.RRId
}).ToList();
Query with Where clause after string Join
// The below query takes so much of time to filter the records.
var NewBibContentsModel = (from x in db.BibContents
select new
{
BibId = x.BibId,
Title = (from a in db.BibContents where a.BibId == x.BibId && a.TagNo == "245" orderby a.Id ascending select a.NormValue),
//Tit = (from a in db.BibContents where a.BibId == line.BibId && a.TagNo == "245" && a.Sfld == "a" select a.NormValue).FirstOrDefault(),
Author = (from a in db.BibContents where a.BibId == x.BibId && splitted.Contains(a.TagNo) && a.NormValue != null select a.TagNo).FirstOrDefault(),
ISBN = (from a in db.BibContents where a.BibId == x.BibId && a.NormValue != null && (a.TagNo == "020" || a.TagNo == "022") orderby a.Id ascending select a.NormValue)
}).AsEnumerable().Select(x => new BibContentsModel
{
BibId = x.BibId,
Title = string.Join(" ", x.Title),
Author = string.Join(" ", (from a in db.BibContents where a.BibId == x.BibId && a.TagNo == x.Author orderby a.Id select a.NormValue)),
ISBN = string.Join(" ", x.ISBN),
RRId = aa.RRId
}).Where (x=> x.Title == aa.CurrentTitle || (x.ISBN == aa.CurrentISBN)).ToList();
Any help or suggestion to this problem will be appreciated.
Thanks,

Related

42P18: could not determine data type of parameter $12

I'm trying to run this query, but it tells me this error:
42P18: could not determine data type of parameter $12
bds.DataSource = (from vendas in conexao.Vendas
join nota in conexao.NotaFiscal on vendas.IdNotaFIscal equals nota.Id
join clientes in conexao.Cliente on vendas.IdCliente equals clientes.Id
where (nota.DataEmissao >= periodoInicial || periodoInicial == null) &&
(nota.DataEmissao <= periodoFinal || periodoFinal == null) &&
(clientes.Id == idCliente || idCliente == null) &&
(nota.NumeroNotaFiscal >= notaInicial || notaInicial == null) &&
(nota.NumeroNotaFiscal <= notaFinal || notaFinal == null) &&
(nota.Modelo == mod || mod == null)
orderby nota.Id descending
select new
{
Id = nota.Id,
ClienteId = clientes.NomeRazao,
Chave = nota.Chave,
DataEmissao = nota.DataEmissao,
Status = nota.Status,
NumeroNota = nota.NumeroNotaFiscal,
Modelo = nota.Modelo,
}).ToList();
The error occurs in this line below, if I withdraw, works normal, I have tried to change, however I need this filter.I can't understand what I'm doing wrong.
(nota.Modelo == mod || mod == null)
And here's how I fill out the variable
string mod = String.Empty;
if(modelo != "TODOS") mod = modelo == "NF-E" ? "55" : modelo== "NFC-e" ? "65" : null;
Any idea how I can fix it? Thank you.
Try to separate filtering. Such parameters is bad for LINQ Translation and performance. I hope it will solve your problem.
var query =
from vendas in conexao.Vendas
join nota in conexao.NotaFiscal on vendas.IdNotaFIscal equals nota.Id
join clientes in conexao.Cliente on vendas.IdCliente equals clientes.Id
select new { vendas, nota, clientes };
if (periodoInicial != null)
query = query.Where(x => x.nota.DataEmissao >= periodoInicial);
if (periodoFinal != null
query = query.Where(x => x.nota.DataEmissao <= periodoFinal);
if (idCliente != null)
query = query.Where(x => x.clientes.Id == idCliente);
if (notaInicial != null)
query = query.Where(x => x.nota.NumeroNotaFiscal >= notaInicial);
if (notaFinal != null)
query = query.Where(x => x.nota.NumeroNotaFiscal <= notaFinal);
if (mod != null)
query = query.Where(x => x.nota.Modelo == mod);
var result =
from q in query
orderby q.nota.Id descending
select new
{
Id = q.nota.Id,
ClienteId = q.clientes.NomeRazao,
Chave = q.nota.Chave,
DataEmissao = q.nota.DataEmissao,
Status = q.nota.Status,
NumeroNota = q.nota.NumeroNotaFiscal,
Modelo = q.nota.Modelo,
};
bds.DataSource = result.ToList();

Shortening loop to one QUERY in LINQ

Below is a piece of code that I do in a loop:
At the beginning, in the first query, I get a list of location IDs. The list can be long.
Ultimately, I need to find for which LocationId FamiliId > 0
I have it done in a loop but I would like to do it in one question. Is it possible and if so how?
var locationIds = context.TblUsersDistricts
.Where(d => d.UserId == userId && d.ValidityTo == null)
.Select(x => x.LocationId).ToList();
int familyId = 0;
foreach(var item in locationIds) {
familyId = (from I in context.TblInsuree
join F in imisContext.TblFamilies on I.FamilyId equals F.FamilyId
join V in imisContext.TblVillages on F.LocationId equals V.VillageId
join W in imisContext.TblWards on V.WardId equals W.WardId
join D in imisContext.TblDistricts on W.DistrictId equals D.DistrictId
where(I.Chfid == chfid &&
D.DistrictId == item &&
F.ValidityTo == null &&
I.ValidityTo == null &&
V.ValidityTo == null &&
W.ValidityTo == null &&
D.ValidityTo == null)
select F.FamilyId)
.FirstOrDefault();
if (familyId > 0) break;
};
It sounds like you want:
var familyId = (
from item in locationIds
from I in context.TblInsuree
// ... etc
&& D.ValidityTo == null)
select F.FamilyId)
.FirstOrDefault();
?

assistance required to convert SQL into LINQ

i am trying to convert the following SQL into LINQ and need some assistance with the nested select clauses for the paid_amount and paid_vat and also for the select within the where clause. Ignore the index things.
here is the SQL
SELECT
tramps.gl_transaction.debtor_uri,
tramps.debtor.account_no,
tramps.gl_transaction.uri as transaction_uri,
tramps.gl_transaction.base_currency_amount,
tramps.gl_transaction.base_currency_vat_amount,
(select IsNull(sum(gltr.base_currency_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) * (-1) as Paid_Amount ,
(select IsNull(sum(gltr.base_currency_vat_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) * (-1) as Paid_Vat ,
tramps.account.property_ref,
tramps.account.sub_ledger_code,
tramps.gl_transaction.transaction_type_code,
tramps.gl_transaction.transaction_description,
tramps.gl_transaction.effective_date
FROM tramps.account, tramps.chart WITH (INDEX (PK_CHART)), tramps.gl_transaction WITH (INDEX (glt_debtor_gen)) ,tramps.debtor, tramps.receivables_register , tramps.bank_account
WHERE tramps.chart.code = tramps.account.chart_code
AND tramps.gl_transaction.debtor_uri = tramps.debtor.uri
AND tramps.gl_transaction.account_uri = tramps.account.uri
AND tramps.receivables_register.uri = tramps.gl_transaction.receivables_register_uri
AND tramps.receivables_register.bank_account_uri = tramps.bank_account.uri
AND tramps.chart.control_account = 'Debtor'
AND tramps.gl_transaction.status = 'L'
AND tramps.gl_transaction.process_status = 'Released'
AND ( (tramps.gl_transaction.generated = 'C' AND tramps.gl_transaction.sibling_uri IS NULL AND tramps.gl_transaction.written_off <> 'Y')
OR (tramps.gl_transaction.generated = 'N' AND tramps.gl_transaction.sibling_uri IS NULL) )
AND (tramps.gl_transaction.base_currency_amount +
(select IsNull(sum(gltr.base_currency_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) <> 0.00 )
this is the LINQ i have managed to create so far, but i am struggling with the nested selects, the sum and the where clause
from acc in Accounts
join chart in Charts on acc.Chart_code equals chart.Code
join gltrans in Gl_transactions on acc.Uri equals gltrans.Account_uri
join debt in Debtors on gltrans.Debtor_uri equals debt.Uri
join recreg in Receivables_registers on gltrans.Receivables_register_uri equals recreg.Uri
join bankacc in Bank_accounts on recreg.Bank_account_uri equals bankacc.Uri
let paidcurrency = from gltrns in Gl_transactions
where gltrns.Sibling_uri == gltrans.Uri
select gltrns.Base_currency_amount
where
chart.Control_account == "Debtor"
&& gltrans.Status == "L"
&& gltrans.Process_status == "Released"
&& acc.Property_ref == 102979
&& ((gltrans.Generated == "C" && gltrans.Sibling_uri == null && gltrans.Written_off != "Y")
|| (gltrans.Generated == "N" && gltrans.Sibling_uri == null) )
select new
{
gltrans.Debtor_uri,
debt.Account_no,
gltrans.Uri,
gltrans.Base_currency_amount,
gltrans.Base_currency_vat_amount,
er = (decimal?)paidcurrency.Base_currency_vat_amount.Sum() ?? 0,
acc.Property_ref,
acc.Sub_ledger_code,
gltrans.Transaction_type_code,
gltrans.Transaction_description,
gltrans.Effective_date
}
This might help out a little. I blended in some fluent syntax to help translate the Sum functions. Let me know if some of these translations help as I can't check it directly without your schema and some data.
var result =
from acc in Accounts
join chart in Charts on acc.Chart_code equals chart.Code
join gltrans in Gl_transactions on acc.Uri equals gltrans.Account_uri
join debt in Debtors on gltrans.Debtor_uri equals debt.Uri
join recreg in Receivables_registers on gltrans.Receivables_register_uri equals recreg.Uri
join bankacc in Bank_accounts on recreg.Bank_account_uri equals bankacc.Uri
// query expression
//let paidcurrency = from gltrns in Gl_transactions
// where gltrns.Sibling_uri == gltrans.Uri
// select gltrns.Base_currency_amount
// change to fluent..
let paid_Amount = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currency_amount * -1 ?? 0.00M).Sum()
// same for Vat..
let paid_Vat = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currency_vat_amount * -1 ?? 0.00M).Sum()
// added another 'let' to use in the where clause..
let base_Currency = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currenct_amount ?? 0.00M).Sum()
where
chart.Control_account == "Debtor"
&& gltrans.Status == "L"
&& gltrans.Process_status == "Released"
&& acc.Property_ref == 102979
&& (
(
gltrans.Generated == "C" &&
gltrans.Sibling_uri == null &&
gltrans.Written_off != "Y"
)
||
(
gltrans.Generated == "N" &&
gltrans.Sibling_uri == null
)
)
&& gltrans.Base_currency_amount + base_Currency != 0.00M
select new
{
gltrans.Debtor_uri,
debt.Account_no,
gltrans.Uri,
gltrans.Base_currency_amount,
gltrans.Base_currency_vat_amount,
//er = (decimal?)paidcurrency.Base_currency_vat_amount.Sum() ?? 0,
paid_Amount,
paid_Vat,
acc.Property_ref,
acc.Sub_ledger_code,
gltrans.Transaction_type_code,
gltrans.Transaction_description,
gltrans.Effective_date
};

Using a condition in LINQ

How can I rewrite this using a condition in LINQ?
If the selectID = zero, I want this to run :
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId)
select p;
If the selectID NOT zero, I want this to run :
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId) &&
(p.Id == selectID)
select p;
This below works, but I have to use a "dummy" second condition (p.hidden == false)
for the ternary operator to work :
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId) &&
(selectID != 0 ? p.Id == selectID : p.hidden == false)
select p;
Is there a way to get rid of (p.hidden == false) because it is not required in the logic and is just there to get the operator to work. thanks
You could use the same Id as the record as fallback value:
var products = from p in product.Table
orderby p.Name
where p.stock == stockId &&
p.Id == (selectID == 0 ? p.Id : selectID)
select p;
However, since that could lead to a less efficient query plan i would simply use an if-else:
var products = product.Table.Where(p => p.stock == stockId);
if(selectID != 0)
products = products.Where(p => p.Id == selectID);
products = products.OrderBy(p=> p.Name);
You could also write it like this:
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId) &&
(p.Id == selectID || selectID == 0)
select p;
The || selectID == 0 just returns true if the ID isn't supplied and still allows the query to run as you intended. The link below was how I learned this simple trick.
http://www.sommarskog.se/dyn-search-2008.html

linq to entities nested select fillout

I'm trying to return a result and a nested result in a linq to entities query.
Orders[] orderlist =
(from m in db.Orders.Include("OrderLines")
where
areas.Contains(m.Area)
&& m.Branch == branch
&& (m.OrderStatus == "1" || m.OrderStatus == "4")
&& m.SpecialInstrs == string.Empty
select m
HOW??---> m.OrderLines = m.OrderLines.Where(p => (p.LineType == "1" || p.LineType == "7") && p.MBomFlag != "C").ToArray()
).ToArray();
The problem is that the include returns all the FK'd OrderLines for each order when I really only want certain order lines.
How do I do this?
Orders and OrderList are both POCO entities generated by L2E and the poco entity generator.
You can manually join them:
Orders[] orderlist = (from m in db.Orders
join p in db.Orderlines
on p.OrderId = m.Id
where areas.Contains(m.Area)
&& m.Branch == branch
&& (m.OrderStatus == "1" || m.OrderStatus == "4")
&& m.SpecialInstrs == string.Empty
&& (p.LineType == "1" || p.LineType == "7")
&& p.MBomFlag != "C"
select m).ToArray();

Categories