I need a Linq with distinct operation in C# app
SQL should be :
select distinct(col1) from tableName;
I read some e.gs and know that i can write Linq like:
var myRes =
(
from a in tableName
select a.col1
).Distinct();
So here is my question:
Does this linq :
get a whole set of col1 from the MSSQL server to the myRes,
then use C# distinct() function to make distinct at my app side?
if it does so ,
can i make it distincted at the server side?
Or it does:
only get the distincted col1 from the MSSQL server,
and nothing to do at my app side?
Thanks a lot!
This should be performing the DISTINCT filter at the database side, unless something else is making the query execute before the filter is applied. You can confirm this by running SQL Server Profiler when the query executes.
The way this works is by using deferred execution. That is, the query doesn't actually run against the database until it needs to. Prior to that, it builds up what's called an expression tree which then gets evaluated against the data source. So you can append more and more IQueryable<T> extension methods on that statement, and they should all translate into a single query against the database.
What you're passing around in this case (myRes) isn't really the result set, it's a reference to the query which will create the result set. The query gets built and evaluated when the enumeration is evaluated into an actual result set. Such as when you call:
.ToList()
.Single()
.SingleOrDefault()
.First()
.FirstOrDefault()
etc.
Basically anything that takes a reference to a query and turns it into an actual value or collection of values.
Related
I am working with MVC Core with EF-6.x and I am using Lambda expression, but my senior told me use LINQ why, because while using lambda with where clause it will pull all the data from database and later it will apply where condition. In case of LINQ if you use where condition it will pull only filtered data. Please let me know what is correct?
e.gLambda: context.tablename.where(condition);// Should I go with this
LINQ: (from T in tablename where t.(condition));// or this?
Please let me know what is correct?
e.gLambda: context.tablename.where(condition);// Should I go with this
LINQ: (from T in tablename where t.(condition));// or this?
Short answer: it doesn't really matter. Since context.tablename ultimately returns an IQueryable<T>, Entityframework will not try to hit the database until you try to iterate the final result from your expression, not to mention, .ToArray() and .ToList() each, does that iteration for you.
Either you used LINQ expression syntax (which gets compiled as LINQ methods) or LINQ methods, when you attempt to begin iterating the results, Entityframework creates an Expression tree for you underneath the hood that consists of your query altogether (including Wheres, Joins, GroupBys, etc). Since the structure of a LINQ might not percisely match the structure of a SQL query (or whatever data-source query), depending on the source (i.e database, e.g SQL Server), Entityframework then attempts to make the best possible optimization to your expression tree so that its structure would match an executable query on the source (e.g SQL Server query). Finally, it translates that expression tree into an actual query and executes it against the data source, and return your data (after doing all the mapping of course).
If you really, and I mean REALLY want to go through the complications of how an IQueryable engine works, I'd suggest taking a walk through Matt Warren's series: 'LINQ: Building an IQueryable provider series'. That's not actually Entityframework but it shares the same concept.
Both syntax will be translated into the same IL code. The difference, if the filter will be applied on server or client side is, if the source is IQueryable<T> or IEnumerable<T>.
my senior told me use LINQ why, because while using lambda with where
clause it will pull all the data from database and later it will apply
where condition.
Your senior is wrong, you can use the statement you prefer they are the same, both will filter the data at database level. If you have Sql Server as database server, you can use Sql Server Profiler to dump the queries executed by both statements and you will see that they are the same.
I have a Linq query that reads from a SQL table and 1 of the fields it returns are from a custom function (in C#).
Something like:
var q = from my in MyTable
select new
{
ID = my.ID,
Amount = GetAmount(ID)
};
If I do a q.Dump() in LinqPad, it shows the results, which tells me that it runs the custom function without trying to send it to SQL.
Now I want to union this to another query, with:
var q1 = (from p in AnotherQuery.Union(q)...
and the I get the error that Method has no supported translation to SQL.
So, my logic tells me that I need to dump q in memory and then try to union to that. I've tried doing that with ToList() and creating a secondary query that populates itself from the List, but that leads to a long list of different errors. Am I on the right track, by trying to get q in memory and union on that, or are there better ways of doing this?
You can't use any custom functions in a LINQ query that gets translated - only the functions supported by the given LINQ provider. If you want your query to happen on the server, you need to stick with the supported functions (even if it sometimes means having to inline code that would otherwise be reused).
The difference between your two queries boils down to when (and where) the projection happens. In your first case, the data from MyTable is returned from the DB - in your sample, just the ID. Then, the projection happens on top of this - the GetAmount method is called in your application for each of ID.
On the other hand, there's no such way for this to happen in your second query, since you're not using GetAmount in the final projection.
You either need to replace the custom function with inlined query the provider understands, or refactor all your queries to use the supported functions in addition with whatever you need to do in-memory. There's no point in giving you any sample code, since it depends entirely on your actual query, and what you're really trying to query for.
I have a simple count query using LINQ and EF:
var count = (from I in db.mytable
where xyz
select I).Count();
the code above shows the query being locked in the database.
while the execute sql executes right away:
var count = db.SqlQuery<int>("select count(*) from mytable where xyz").FirstOrDefault();
the code above returns immediately.
I few have suggested to remove the .ToList() which I did and not difference. One thing is that this only happens on the PROD server. The QA server executes pretty fast as expected. But the prod server shows that it gets suspended. I suspect this could be a data storage limitation or server related. But wanted to make sure I am not doing something stupid in the code.
UPDATE:
One thing I noticed is the first time it execute is takes longer the first time. When I set next statement to run it again, it executes immediately. Is there a compile of the query the first time?
Because you are calling ToList in the first query and that causes fetching all records from DB and do the counting in memory. Instead of ToList you can just call Count() to get the same behaviour:
var count = (from I in db.mytable
where xyz
select I).Count();
You must not call .ToList() method, because you start retrieve all objects from database.
Just call .Count()
var count = (from I in db.mytable
where xyz
select I).Count();
Count can take a predicate. I'm not sure if it will speed up your code any but you can write the count as such.
var count = db.mytable.Count(x => predicate);
Where predicate is whatever you are testing for in your where clause.
Simple fiddling in LINQPad shows that this will generate similar, if not exactly the same, SQL as above. This is about the simplest way, in terseness of code, that I know how to do it.
If you need much higher speeds than what EF provides, yet stay in the confines of EF without using inline SQL you could make a stored procedure and call it from EF.
Is it possible to use custom method In query for example:
var result = from u in context.MyTable where MyMethod(u) == 10 select u;
As Pranay explains, you cannot have a custom (C#) method as part of the LINQ to SQL query, because LINQ to SQL wouldn't be able to look at the expression tree of the method and so it cannot translate it to SQL.
One option that you have is to write your function in SQL and store it as a SQL function on the SQL Server (possibly, you could also use SQL CLR, but I have not tried that). Then you can add the function to your DataContext type and LINQ to SQL will translate it to calls to the function on SQL server. Something like:
var result = from u in context.MyTable
where context.MyMethod(u) == 10 select u;
The problem, of course, is that you'll need to write the function in SQL (I think SQL CLR could also work - not sure about the performance and other possible complications though)
I also wrote an article (some time ago) that shows how to do this when you write the "method" as an expression tree way (as a value of type Expression<Func<...>>), which is possible, because in this case, the code is compiled as an expression tree. However, there is some postprocessing that has to be done and you can still write just a single expression that can be easily inlined in the LINQ query.
Check this full article : What is and what isn't possible with linq
Following is not possible
// function used in filter
static bool MyFunc(Nwind.Product p)
{
return p.ProductName.StartsWith("B");
}
// query that uses MyFunc
var q =
from p in db.Products
where MyPriceFunc(p.UnitPrice) > 30m
select p
It compiles with no errors, but when you execute it LINQ to SQL throws an exception saying: "Static method System.Boolean MyTest(LINQTest.Nwind.Product) has no supported translation to SQL."
The exception is actually thrown when you try to fetch results from q (for example using the foreach statement), because LINQ to SQL attempts to convert the expression trees to T-SQL only when the results are needed and the query must be executed.
To fix the example you can simply copy the code that checks whether product name starts with "B" to the where clause of the query and it would work fine.
Yes, but if you are using Linq-to-Sql - your method has to have special code to handle to SQL conversion.
I have a LINQ to SQL query that when executed does not return any data. However, when I debug, I can take the generated SQL query, plug in the values for the variables, and run it in SQL Management Studio to get the record I'm expecting. I'm taking the values for the variables while in debug mode as well.
Has anyone experienced something like this before?
As requested, LINQ statement (edited table and column names):
var q1 = from rr in db.ABC
from rd in db.DEF
where rr.a == rd.b
where rr.c == rd.c
where rr.d.Equals(id)
where rr.c.Equals(anotherId)
select new
{
rr.d, rr.x, rr.a,
rr.y, rr.z, rr.v,
rr.e, rd.r
};
var r1 = q1.Single();
I'm using very similar queries in other places with success.
Run the SQL Server profile, take the EXACT query it's running (you shouldn't have to "plug in" any values), and run that.
Are you still obtaining results?
Is it plugging in the correct values?
Are you querying a nullable value?
Could you show us the code and generated query?
I would double check the connection string that LINQ to SQL is using. It might just be hitting the wrong database.
Have you run Profiler to make sure the values you think the stament is going to have are actually inthe statment that was sent to the server?