SQL:
select *
from INVOICE inv WITH(NOLOCK)
inner join ERP_TRANSACTION erpt WITH(NOLOCK) on inv.Id = erpt.Id
inner join ERP_TRANSACTION_LOG erptl WITH(NOLOCK) on inv.InvoiceId = erptl.FimId
Linq:
from inv in _invoiceService.QueryableAsNoTracking()
join erpt in _erpTransactionService.QueryableAsNoTracking() on inv.Id = erpt.Id
join erpt1 _erpTransactionLogService.QueryableAsNoTracking() on inv.InvoiceId = erptl.FimId
select new Model {}
I'm trying to convert my SQL query to a linq query but I couldn't figure out the linq equivalent of WİTH(NOLOCK).
You effectively need to use a "IsolationLevel.ReadUncommitted". It means that the query doesn't care if stuff is in the process of being written to the rows it's reading from - it'll read that "dirty" data and return it as part of the result set.
using (var txn = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted
}
))
{
// Your LINQ to SQL query goes here
}
Link to original post - Link
Related
Problem Statement:
I'm trying to convert one of my Sql to linq query, but I'm unable to get the desired output which i need. Can anyone suggest me what i should do?
SQL Query:
SELECT AssetTagging.AssetID, AssetTagging.AssetDescription, [Return].RequestStatus
FROM AssetTagging
LEFT OUTER JOIN [Return] ON AssetTagging.AssetID = [Return].AssetID
LEFT OUTER JOIN Issue ON AssetTagging.AssetID = Issue.AssetID
WHERE (Issue.AssetID IS NULL) OR ([Return].RequestStatus = 'Approved')
Linq Query I'm using:
var result = (from at in db.AssetTagging.AsEnumerable()
join r in db.Return on at.AssetID equals r.AssetID
orderby at.AssetID
where !db.Issue.Any(issue=>issue.AssetID==at.AssetID) || r.RequestStatus=="Approved"
select new globalTestModel
{
model1=at
}).ToList();
//I know that in Linq query I'm using Inner join instead of Left Join,but i'm getting error if i use left join instead of inner join?
What am I doing wrong??
Any suggestion to get desired query like Sql in Linq?
Asset Tag table:
Issue table:
Return table:
Desired Output :
You need to remove .AsEnumerable(), because you want your query to be translated to sql. Right now it would be using linq-to-objects and if you are using a left join with linq-to-object you need to check for null reference exceptions. rt could be null, so rt.RequestStatus would throw an exception.
*I believe rt should be r in your example
You can't project to an existing entity, so you need to change your select to:
select new PocoClass
{
model1=at
}
//New class definition
public PocoClass
{
public AssetTagging model1 { get; set; }
}
You need to do like this:
var result = from at in db.AssetTagging
join r in db.Returns on at.AssetID equals r.AssetID into a
from returns into a.DefaultIfEmpty()
join i in db.Issues on at.AssetID equals I.AssetID into b
from issues into b.DefaultIfEmpty()
where issues.AssetID != null || returns.RequestStatus == "Approved"
select new
{
AssetID = at.AssetID,
AssetDescription = at.AssetDescription,
Status = returns != null ? returns.RequestStatus : null
}.ToList();
try like following:
from at in db.AssetTagging
join r in db.Return on at.AssetID equals r.AssetID into res1
from atr in res1.DefaultIfEmpty()
join i in db.Issues on i.AssetID==at.AssetID into res2
from obj in res2.DefaultIfEmpty()
select at
where i.AssetID == null || r.RequestStatus equals "Approved"
Just make two times left outer join and then do filter on where condition.
Also have first look at this msdn article about left outer join using linq.
Try the following I am assuming that you still want the cases where r is null unless r is not null and request status = approved.
You have to check to verify r!=null before checking the request status and you will still need to include when r is null to get the complete result set. I haven't tested this, but this should put you in the right direction.
Good luck.
var result = (from at in db.AssetTagging
join r in db.Return.DefaultIfEmpty()
on at.AssetID equals r.AssetID
join i in db.Issue.DefaultIfEmpty()
on at.AssetID equals i.AssetID
where
(r == null || (r!=null && r.RequestStatus == "Approved"))
|| i == null
select new {
at.AssetID,
at.AssetDescription,
IssueID = (i!=null) ? i.IssueID : null),
ReturnID = (r!=null) ? r.ReturnID: null),
ReturnStatus = (r!=null)
? r.ReturnStatus
: null}).ToList();
I know this isn't exactly what you've asked for, but it might be useful anyway.
If you have access to the database to execute SQL queries, I would suggest creating a view. You can then drop the view into your DBML file the same way as you would with a table, and have much simpler Linq expressions in your C# code.
CREATE VIEW [Asset_Issue_Return_Joined] AS
SELECT AssetTagging.AssetID, AssetTagging.AssetDescription, [Return].RequestStatus
FROM AssetTagging
LEFT OUTER JOIN [Return] ON AssetTagging.AssetID = [Return].AssetID
LEFT OUTER JOIN Issue ON AssetTagging.AssetID = Issue.AssetID
WHERE (Issue.AssetID IS NULL) OR ([Return].RequestStatus = 'Approved')
Here is the complete query
var result = (from assetTagging in db.AssetTagging
join return0 in db.Return on assetTagging.AssetID equals return0.AssetID into returns
from return0 in returns.DefaultIfEmpty()
join issue in db.Issue on assetTagging.AssetID equals issue.AssetID into issues
from issue in issues.DefaultIfEmpty()
where issue.AssetID == null || return0.RequestStatus == "Approved"
select new
{
assetTagging.AssetID,
assetTagging.AssetDescription,
return0.RequestStatus
}).ToList();
I have the following SQL query
SELECT *
FROM LOC l
JOIN CLA c ON l.IdLoc = c.IdLoc
JOIN FA f on c.IdCla = f.IdCla
LEFT JOIN CON co ON f.IdCla = co.IdCla
AND co.DeletedDate IS NULL
AND co.IdUser = f.IdUser
WHERE f.IdUser = 7
AND f.DeletedDate IS NULL
I would like to convert it to LINQ but I'm absolutely not at ease with LEFT JOIN and "temp table" with LINQ.
Moreover, I tried to convert it but it seems it is impossible to create a join clause with a WHERE inside in LINQ (Linqer told me that and Linqpad doesn't seem able to convert from SQL to LINQ in free version)
Could you give me clue ?
Thanks a lot
I think you are looking for something like this. I left out the select clause so that you can pull out what you need. Things to note:
To join multiple columns, create anonymous types. The field names in the anonymous types must match.
To create a =NULL condition, create a variable name that matches the field name in the other entity. Set it =null but coerce it to the nullable data type of the field you are setting it equal to.
Edit: Updated query to move where clause to joins
from l in LOC
join c in CLA
on l.IdLoc equals c.IdLoc
join f in FA
on new { c.IdCla, IdUser = 7, DeletedDate = (DateTime?)null }
equals new { f.IdCla, f.IdUser, f.DeletedDate }
join co in CON
on new { f.IdCla, DeletedDate = (DateTime?)null, f.IdUser }
equals new { co.IdCla, co.DeletedDate, co.IdUser } into lj
from l in lj.DefaultIfEmpty()
Can someone help me convert this SQL Query to EntityFramework LINQ. I don't know how to do Inner Join in EF.
select * from UserActivities INNER JOIN LoginHistories
ON UserActivities.iLoginHistoryId = LoginHistories.iLoginHistoryId
AND iUserId = 15
It is just a rough estimate (not enough context):
var db = GetDbContextSomehow();
var query = from ua in db.UserActivities
join lh in db.LoginHistories on ua.iLoginHistoryId equals lh.iLoginHistoryId
where ua.iUserId == 15
select ua;
When this gets called two times, the second invocation doesn't re-run the query on the database, the query caching works.
var query = from p in session.Query<Product>()
where p.YearIntroduced >= 0
select p;
query = query.Cacheable();
var t = query.ToList();
However, when I put some join on the query, the query cache is not working anymore, hence when this is invoked two times, the query is invoked on database two times too:
var query = from p in session.Query<Product>()
join l in session.Query<ProductLanguage>()
on p.ProductId equals l.ProductId
where p.YearIntroduced >= 0
select new { p, l };
query = query.Cacheable();
var t = query.ToList();
Might be a dumb question, is query caching can work on one table only, hence when adding a join, the query is not cacheable anymore?
What's the solution to make a query cacheable even it has a join?
Another oddity, the query caching with join will work if I remove the where clause. When this gets called two times, the second invocation doesn't re-run the query on database, the query caching works
var query = from p in session.Query<Product>()
join l in session.Query<ProductLanguage>()
on p.ProductId equals l.ProductId
select new { p, l };
query = query.Cacheable();
var t = query.ToList();
But what's the use of a query when you can't put a where clause on it?
Is this an NHibernate bug, or am I just using query caching the wrong way?
Found the solution, put the Where clause on the final part of the query:
var query = from p in session.Query<Product>()
join l in session.Query<ProductLanguage>()
on p.ProductId equals l.ProductId
select new { p, l };
query = query.Where(x => x.p.ProductId && x.l.LanguageCode == "en").Cacheable();
var t = query.ToList();
I have an issue with Linq to Nhibernate producing queries with outer joins.
For example:
return Session.Linq<ClientContact>().Where(c => c.Client.Id = 13).ToList();
Produces a query similar to:
SELECT...
FROM mw_crafru.clientcontact this_,
mw_crafru.client client1_,
mw_crafru.relationshiptype relationsh4_
WHERE this_.clientid = client1_.clientid(+)
AND this_.relationshiptypeid = relationsh4_.relationshiptypeid
AND client1_.clientid = :p0;:p0 = 13
Notice the outer join this.clientid = client1.clientid(+). Boo!
To resolve the issue I went back to using Session.CreateCriteria.
return Session.CreateCriteria(typeof (ClientContact)).Add(Restrictions.Eq("Client.Id", clientId)).List<ClientContact>();
Produces the following query:
SELECT...
FROM mw_crafru.clientcontact this_,
mw_crafru.client client1_,
mw_crafru.relationshiptype relationsh4_
WHERE this_.clientid = client1_.clientid
AND this_.relationshiptypeid = relationsh4_.relationshiptypeid
AND client1_.clientid = :p0;:p0 = 13
Notice no outer join this.clientid = client1.clientid. Yay!
Anyone know why this is happening?
With SQL Server at least, a many-to-one mapping with not-null="true", or Not.Nullable() using Fluent NH, causes Get operations to use an inner join instead of a left join. Try adding that to your mapping for Client in ClientContact.