This question already has answers here:
How to do a subquery in LINQ?
(6 answers)
Closed 9 years ago.
SELECT userid FROM userTable
WHERE userid in (select writeuserid FROM boardTable)
C# LINQ expressions, how to use a query?
I have been using EF4.
userTable, boardTable is connected to the DbContext.
Why not have two different LINQ queries, so that your inner query doesn't execute for each iteration of the outer query.
var query1 = (from t in dbContext.boardTable
select t.writeuserid).ToArray();
var query2 = from r in dbContext.userTable
where query1.Contains(r.userid)
select r.userid;
If your situation is as simple as in the question then you cause join in linq
Assume in here you use Entity FrameWork, so you can use Join to get the result, below is to use the lambda expression:
var result = dbContext.Users.Join(dbContext.Boards,
user => user.UserId,
board => board.WriteUserId,
(u, b) => u.UserId);
why not using join?
var result = (from u in dbcontext.userTable
join u1 in dbcontext.boardTable on u.userid equals u1.writeuserid
select u.userid).FirstOrDefault();
if (result != null)
// do anything else
else
// user not exists
Related
Anyone can help me how to convert sql statement to linq and lambda like this ?
SELECT
tbl_terms.ID,
tbl_terms.Terms
FROM
tbl_terms
LEFT JOIN tbl_asn_uploaddoc ON tbl_terms.ID != tbl_asn_uploaddoc.Id_term
WHERE
tbl_asn_uploaddoc.Nip = '201948274838491943' && tbl_asn_uploaddoc.STATUS = 1
Thanks in advance
LINQ is mostly similar to SQL if you use query syntax instead of method syntax. Here is what I could gather quickly. Can't test because I don't have your model classes.
var Result = from t in context.tbl_terms
join d in context.tbl_asn_uploaddoc on t.ID != d.Id_term
where d.Nip = '201948274838491943' && d.STATUS = 1
select t.ID, t.Terms
Use below query that will give you LEFT JOIN on both of your entity,
var result = (from t in _con.tbl_Terms
join u in _con.tbl_asn_uploaddocs on t.ID equals u.Id_term
into tu
where !tu.Any()
from u in tu.DefaultIfEmpty()
where u.Nip == "201948274838491943" && u.STATUS == 1
select new
{
ID = t.ID,
Terms = t.Terms
}).ToList();
Where _con is your context.
You can use SQL to LINQ converter tool Linqer
Linqer is a SQL to LINQ conversion tool. It helps learning LINQ and convert existing SQL statements.
This question already has answers here:
Linq to Entity Join table with multiple OR conditions
(3 answers)
Closed 6 years ago.
So what I'm trying to do is :-
SELECT * FROM TableA
JOIN TableB ON TableA.OriginPhoneNumber=TableB.Id OR TableA.DestinationPhoneNumber=TableB.Id
Rather strange query I know! But I'm trying to replicate this in EntityFramework/Linq - looking at all the samples I can see a pretty easy way to do it when the join is using an AND (using anonymous types) but does the same result exist for a OR join?
Just do a cross join with a where clause
var results = from a in db.TableA
from b in db.TableB
where a.OriginPhonenumber == b.Id
|| a.DestinationPhoneNumber == b.Id
select new { A = a, B = b };
It's doubtful that an or in a join condition would be more efficient than this, but it's likely that either would result in the same execution plan. Performance aside it will give the same results.
I used Union
var firstJoin=from tbl in TableA
join c in TableB
on c.OriginPhoneNumber Equals tbl.Id
var secondJoin=from tbl in TableA
join c in TableB
on c.DestinationPhoneNumber Equals tbl.Id
var result=firstJoin.Union(secondJoin)
My question got down voted and put on hold because it is not specific enough. Ill try to specify
Before linq I would do this query
sql="SELECT products.* FROM products INNER JOIN productaccess ON products.id=productaccess.productid"
Now with the entity framework and link I can do this
var products = (from lProducts in db.Products
join lProductAccess in db.ProductAccess on lProducts.ID equals lProductAccess.ProductID
select lProducts).ToList();
But what if I want the flexibilty to get all products or only get the accessible objects
In sql I can do this
sql="SELECT products.* FROM products "
if (useProductAccess) {
sql+=" INNER JOIN productaccess ON products.id=productaccess.productid"
}
In Linq I have to make a separate linq statement.
if (useProductAccess) {
var productsFiltered = (from lProducts in db.Products
join lProductAccess in db.ProductAccess on lProducts.ID equals lProductAccess.ProductID
select lProducts).ToList();
} else {
var productsAll = (from lProducts in db.Products select lProducts).ToList();
}
Now, I could just get all the lProducts and then filter it in an additional linq statement with lProductAccess but then I am using an unnecessary large amount of data.
Is it an option to use:
var productsAccecible = (from lProductAccess in db.ProductAccess where lProductAccess.CustID==custID select lProductAccess).toArray();
var products = (from lProducts in db.Products
where (useProductAccess ?
productsAccessible.Contains(lProducts.ID)
: true)
select lProducts).ToList();
Linq provider will not know how to transform the ternary operator (? and :) in a valid sql, you could try this:
var query = db.Products;
if (useProductAccess)
query = query.Where(p => productsAccessible.Contains(p.ID));
var result = query.ToList();
I used the express profiler to see how the linq statement is translated into sql. It shows that the
productsAccessible.Contains(lProducts.ID)
part gets translated as
products.id in (comma seperated list of values)
My conclusion is it will work fine.
Are there possible drawbacks
Sure - it may produce an inefficient query, or it may not even work.
One thing to note is that your conditional operator won't compile; you can't return a bool and an int from the ternary operator.
Maybe you mean:
var products = (from lProducts in db.Products
where (useProductAccess ?
productsAccessible.Contains(lProducts.ID)
: true)
select lProducts).ToList();
or build your query up using method syntax and only add the where clause if necessary.
This question already has an answer here:
What is meant by 'The specified LINQ expression contains references to queries that are associated with different contexts'
(1 answer)
Closed 8 years ago.
I am trying to join 3 tables using LINQ from 2 different SQL Servers (entities).
Error: The specified Linq expression contains references to queries that are associated with different contexts
var query = from a in EntityA.TableA
join p in EntityA.TableB
on a.PersonID equals p.PersonID
join m in EntityB.TableC
on Convert.ToInt32(a.SourceID) equals m.ID
where p.someID == "100000527"
select m.ID;
Please help me to resolve this.
Answer:
var query = from a in EntityA.TableA
join p in EntityA.TableB
on a.PersonID equals p.PersonID
where p.someID == "100000527"
select a.ID;
IQueryable<int> ID = null;
foreach (var item in query)
{
int sourceID= Convert.ToInt32(item);
ID = (from m in EntityB.TableC
where m.ID == sourceID
select m.ID).Distinct();
}
return ID;
Is this right approach?
You can only write Linq to SQL Queries on one database at a time.
If you want to join the data together, you will have to write the two queries separately, create anonymous type objects from them, then join them together using plain old Linq on objects.
I'm using the following query and am having trouble figuring out how to add a join into it:
var chi = Lnq.attlnks.Where(a => a.ownerid == emSysid)
.Select(c => new { sysid });
How can I join this to the "attach" table (ON attlnks.sysid = attach.sysid) and select "name" where sysid is the row id?
For joins in Linq the query expression form is typically more readable than lambda syntax - I believe this is what you are asking for:
var chi = from t in Lnq.attach
join a in Lnq.attlnks
on t.sysid equals a.sysid
where a.ownerid == emSysid
select t.name;
If there is only a single entry that should match at most, you can chain a FirstOrDefault() in this case (or other alternatives like SingleOrDefault, Single, First etc.):
var chi = (from t in Lnq.attach
join a in Lnq.attlnks
on t.sysid equals a.sysid
where a.ownerid == emSysid
select t.name).FirstOrDefault();
If I understood your problem, this should work fine:
var query = from a in attlinks
join aa in attach on a.sysid equals aa.sysid into a2
where a2.sysid == a2.ownerid
select a2.Name;