This code is giving inaccurate results and I need to change it but I do not understand what the whole code is doing.
I read about defaultifempty and its implementation. I read the documentation but I could not find the answer to the question.
var records = from entity in _db.InventoryDetails
from am in _db.AccountMeters
.Where(am => entity.SerialNumber == (am.SerialNumber ?? am.RemoteId.ToString())).DefaultIfEmpty()
from ac in _db.Accounts
.Where(ac => ac.AccountId == am.AccountId).DefaultIfEmpty()
from i in _db.Inventories
.Where(idd => idd.ProjectId == projectid)
.Where(idd => idd.InventoryId == entity.InventoryId)
from u in _db.Users
.Where(e => e.Id == (entity.InstallerId ?? entity.PrevInstaller)).DefaultIfEmpty()
It does not give error just the query is giving wrong result. If I can find sql equivalent for the code then I can find out what he was trying to do and then find out business requirement and re code.
You can get SQL code which will be generated by your code through calling ToString() method:
var records = from entity in _db.InventoryDetails
// the other code is omitted for the brevity
var sqlCode = records.ToString(); // here your generated SQL code
With EF 6 and beyond, you can use
context.Database.Log = Console.Write;
to write the SQL to the console.
Related
Have a OData Web Service that I want to query and apply conditional processing to but the following error is being recieved "Error translating Linq expression to URI: Can only specify query options (orderby, where, take, skip) after last navigation"
var reason = (from x in odataContainer.Table where x.userId == "test" select x.eventReason );
if (eventReason == "Failure")
// Do something
The query does work if I don't make the selection specific i.e select x instead of x.eventReason however I want to avoid pulling back a lot of data by applying a filter.
Any suggestions on how to make this work?
Try this,
var reason = odataContainer.Table.Where(x => x.UserId == "test").FirstOrDefault().eventReason;
This should work!
How can I make this lesser than or equal work in my .Where() clause? I am getting an error.
var filteredProducts = Products.Where(p => p.State.Contains("Bruikbaar"))
.Where(p => p.Privilege <= ui.GetPrivilegeNumber())
.ToList();
Error:
LINQ to Entities does not recognize the method 'Int32 GetPrivilegeNumber()' method, and this method cannot be translated into a store expression.
I hope this question is never asked before. Googled couldn't find it either or I am using the wrong words to express my problem.
ui.GetPrivilegeNumber() is not a recognized method.
Use this:
var uiPrivilege = ui.GetPrivilegeNumber();
var filteredProducts = Products.Where(p => p.State.Contains("Bruikbaar"))
.Where(p => p.Privilege <= uiPrivilege)
.ToList();
And as other users mentionted, you can optimize your Where.
EF does not execute method calls which you use in predicates. It stores them as expression (i.e. syntax tree) and then analyzes this tree to build SQL query by translating C# code to SQL code. It cannot translate GetPrivilegeNumber() method call into SQL, because there is no appropriate SQL code for that. So all you need is move this method call out of expression and pass only result of method call instead:
var privilegeNumber = ui.GetPrivilegeNumber();
var filteredProducts = Products.Where(p => p.State.Contains("Bruikbaar"))
.Where(p => p.Privilege <= privilegeNumber)
.ToList();
Now privilegeNumber is just an integer variable which is translated into SQL parameter
SELECT * FROM Products p
WHERE p.State LIKE '%Bruikbaar%' AND p.Privilege <= #privilegeNumber
You need to move ui.GetPrivilegeNumber() outside of the query. You can also merge those Where queries into a single one:
var privilegeNumber = ui.GetPrivilegeNumber();
var filteredProducts = Products.Where(p =>
p.State.Contains("Bruikbaar")
&& p => p.Privilege <= privilegeNumber)
.ToList();
You can use other evaluation method inside LinQ. To simplified the code, you can use it in little old way of writing LinQ.
var uiPrivilege = ui.GetPrivilegeNumber();
var filteredProducts =(from p in Products
where p.State.Contains("Bruikbaar") && p.Privilege <= uiPrivilege
select p).ToList();
The above query generate same output but easy to understood.
I am relatively new to Entity Framework 6.0 and I have come across a situation where I want to execute a query in my C# app that would be similar to this SQL Query:
select * from periods where id in (select distinct periodid from ratedetails where rateid = 3)
Is it actually possible to execute a query like this in EF or would I need to break it into smaller steps?
Assuming that you have in your Context class:
DbSet<Period> Periods...
DbSet<RateDetail> RateDetails...
You could use some Linq like this:
var distincts = dbContext.RateDetails
.Where(i => i.rateId == 3)
.Select(i => i.PeriodId)
.Distinct();
var result = dbContext.Periods
.Where(i => i.Id)
.Any(j => distincts.Contains(j.Id));
Edit: Depending on your entities, you will probably need a custom Comparer for Distinct(). You can find a tutorial here, and also here
or use some more Linq magic to split the results.
Yes, this can be done but you should really provide a better example for your query. You are already providing a bad starting point there. Lets use this one:
SELECT value1, value2, commonValue
FROM table1
WHERE EXISTS (
SELECT 1
FROM table2
WHERE table1.commonValue = table2.commonValue
// include some more filters here on table2
)
First, its almost always better to use EXISTS instead of IN.
Now to turn this into a Lambda would be something like this, again you provided no objects or object graph so I will just make something up.
DbContext myContext = this.getContext();
var myResults = myContext.DbSet<Type1>().Where(x => myContext.DbSet<Type2>().Any(y => y.commonValue == x.commonValue)).Select(x => x);
EDIT - updated after you provided the new sql statement
Using your example objects this would produce the best result. Again, this is more efficient than a Contains which translates to an IN clause.
Sql you really want:
SELECT *
FROM periods
WHERE EXISTS (SELECT 1 FROM ratedetails WHERE rateid = 3 AND periods.id = ratedetails.periodid)
The Lamda statement you are after
DbContext myContext = this.getContext();
var myResults = myContext.DbSet<Periods>()
.Where(x => myContext.DbSet<RateDetails>().Any(y => y.periodid == x.id && y.rateid == 3))
.Select(x => x);
Here is a good starting point for learning about lamda's and how to use them.
Lambda Expressions (C# Programming Guide).
this is your second where clause in your query
var priodidList=ratedetails.where(x=>x.rateid ==3).DistinctBy(x=>x.rateid);
now for first part of query
var selected = periods.Where(p => p.id
.Any(a => priodidList.Contains(a.periodid ))
.ToList();
I have following QueryOver which throws NullReferenceException when newExam.ActiveTo is null (ActiveTo type is DateTime?)
Exam examAlias = null;
examsInSameTime = session.QueryOver(() => examAlias)
.Where(() => examAlias.ActiveTo == null && newExam.ActiveTo == null)
.Future<Exam>();
When I rewrote query to this HQL everything works fine
var query = "from Exam exam where exam.ActiveTo is null and :newExamActiveTo is null)";
examsInSameTime = session.CreateQuery(query)
.SetParameter("newExamActiveTo", newExam.ActiveTo).List<Exam>();
Why QueryOver throws exception and HQL not?
I would say, that solution here should be surprisingly simple and elegant (but only if I do read your issue correctly).
The point is - check your params in C#, do not send that into DB side:
Exam examAlias = null;
var query = session.QueryOver(() => examAlias);
//here we will check what needed
if(newExam.ActiveTo == null)
{
query.Where(() => examAlias.ActiveTo == null)
}
// we can repeat that many times and build WHERE clause as required
...
// finally the query
examsInSameTime = query.Future<Exam>();
So, the trick here is:
check the search params on application side
if needed, convert them into SQL WHERE statement
send on DB side only restrictions which are required
As written by Radim, you are using a parameter inside the QueryOver. The problem is that newExam is probably null when you execute the query.
I am new to NHibernate and while exploring it I got into trouble with the following query which gives me a "Specified method is not supported." error, any ideas why?
var merchantSite = session.Query<MerchantSite>().FirstOrDefault(x => x.Site.Id == SiteId);
var customers = session.Query<Customer>().Where(x => x.Transaction.Any<Transaction>(y => merchantSite.Transaction.Any<Transaction>(c => c.Id == y.Id))).ToList();
Both MerchantSite and Transaction have a list of objects of type Transaction.
There must be someone out there who has been in the similar situation, please share with us your experience, what should we do in this situation?
Thanks in advance!
When you do the ToList call, that's when nHibernate is building the necessary SQL to run the query and it's basically saying that it's having trouble translating that into a single SQL call.
If x.Site is null, then you'd get "specific method is not supported." You could try writing
FirstOrDefault(x => x.Site != null && x.Site.Id == SiteId);
or using C# 6
FirstOrDefault(x => x.Site?.Id == SiteId);