I have been working with Oracle SQL for a while and am currently developing an MVC application in my spare time. At the moment I stuck on an INNER JOIN lambda expression, I have no idea how to convert the SQL statement to C# lambda expression, I've had a look at other answers similar to this question but none provide the answer and a detailed description of how to convert the statement.
Code:
SELECT
t.name, t.description
FROM
TOPICS t
INNER JOIN
TOPIC_SUBSCRIPTIONS
ON
t.TOPICID = TOPIC_SUBSCRIPTIONS.TOPICID
WHERE
TOPIC_SUBSCRIPTIONS.MEMBERID = 96;
Solution 1:
var q = db.Topics
.SelectMany(t => t.TopicSubscriptions, (t, ts) => new { t, ts })
.Where(sub => sub.ts.MemberId == 96)
.Select(sub => new { sub.t.Name, sub.t.Description });
or using LINQ style
var q = from t in db.Topics
from ts in topic.Subscriptions
where ts.MemberId == 96
select new { t.Name, t.Description };
Solution 2
var q = from t in db.Topics
join ts in db.TopicSubscriptions on t.TopicId equals ts.TopicId
into ij
from tsub in ij
where tsub.MemberId == 96
select new { t.Name, t.Description};
Related
Can anybody please help with this SQL query to transform it to EF Linq Expression?
select MI.Id, B.Count, B.Cost, Name, Price, Unity, I.Count, I.Cost, BOL.Date, BOL.type, BOL.Number
from Balance B inner join MaterialsInfo MI on Mi.Id = B.MaterialsId
inner join Income I on MI.Id = I.MaterialsId
inner join BillOfLading BOL on I.BillOfLadingId = BOL.Id
where B.Id in (select Id from (select max(Date), Id from Balance group by Balance.MaterialsId))
and I.Id in (select Id from(select max(Date), Income.Id as Id from Income inner join BillOfLading BOL on Income.BillOfLadingId = BOL.Id group by Income.MaterialsId))
I've been trying to do this for days, so I could really use some help.
Do you need extra info?
Thank you in advance.
Edit
Here is a little part of the diagram, maybe it helps
It seems the subqueries in both of your conditions in where clause is incorrect. Because your
group by column is missing in the select statement
And it is very unclear what you trying to achieve from the subqueries.
Without a clear understanding of your subqueries, all I can prepare for you is this.
var result = await (from balance in yourDBContect.Balances
join material in yourDBContect.MaterialsInfos on balance.MaterialsId equals material.Id
join income in yourDBContect.Incomes on material.Id equals income.MaterialsId
join bill in yourDBContect.BillOfLadings on income.BillOfLadingId equals bill.Id
where Balances.GroupBy(g => g.MaterialsId)
.Select(s => new
{
MaterialsId = s.Key,
MaxDate = s.Max(x => x.Date)
}).ToList().Contains(new { balance.MaterialsId, MaxDate = balance.Date })
&& Incomes.Join(BillOfLadings,
p => p.BillOfLadingId,
e => e.Id,
(p, e) => new { p, e })
.GroupBy(g => g.p.MaterialsId)
.Select(s => new
{
MaterialsId = s.Key,
MaxDate = s.Max(s => s.e.Date)
}).ToList().Contains(new { income.MaterialsId, MaxDate = balance.Date })
select new
{
material.Id,
balance.Count,
balance.Cost,
balance.Name,
balance.Price,
balance.Unity,
ICount = income.Count,
ICost = income.Cost,
bill.Date,
bill.Type,
bill.Number
});
Notes:
Alias for Income.Count and Income.Cost are changed because an object cannot contain exactly same nenter code hereamed property.
Linq for a proper subquery will replace new List<int>().
How can I convert left join to linq script. I have a T-SQL like this:
SELECT
es.StandardID,
COUNT(DISTINCT esc.StandardCourseID) AS CourseIDCount,
COUNT(DISTINCT esp.StandardPostID) AS PostIDCount
FROM EduStandards AS es
LEFT JOIN EduStandardCourses AS esc
ON es.StandardID = esc.StandardID
LEFT JOIN EduStandardPosts AS esp
ON es.StandardID = esp.StandardID
GROUP BY es.StandardID
That I want to convert this to linq.
Following is the query with left join that is replica of your query in linq.
var query = (from es in dbContext.EduStandards
join esc in dbContext.EduStandardCourses on es.StandardID equals esc.StandardID into ssc
from esc in ssc.DefaultIfEmpty()
join esp in dbContext.EduStandardPosts on es.StandardID equals esp.StandardID into ssp
from esp in ssp.DefaultIfEmpty()
select new { StandardId = es.StandardID, CourseCount = ssc.Count(), PostCount = ssp.Count() }).Distinct().ToList();
But I think we need not to apply left join in linq to calculate count. Following optimized linq query will return same result.
var query2 = (from es in dbContext.EduStandards
join esc in dbContext.EduStandardCourses on es.StandardID equals esc.StandardID into ssc
join esp in dbContext.EduStandardPosts on es.StandardID equals esp.StandardID into ssp
select new { StandardId = es.StandardID, CourseCount = ssc.Count(), PostCount = ssp.Count() });
This is what I've come up with
var query = from es in db.EduStandards
join esc1 in db.EduStandardCourses
on es.StandardId equals esc1.StandardId into esc
from c in esc.DefaultIfEmpty()
join esp1 in db.EduStandardPosts
on es.StandardId equals esp1.StandardId into esp
from p in esp.DefaultIfEmpty()
group new { es.StandardId, Course = c, Post = p } by es.StandardId into g
select new
{
StandardId = g.Key,
CourseIdCount = g.Where(x => x.Course != null).Count(),
PostIdCount = g.Where(x => x.Post != null).Count(),
};
However, I'm not entirely sure if it'll work for EF.
You could always do something like this:
var query = from es in db.EduStandards
select new
{
es.StandardId,
CourseIdCount = db.EduStandardCourses.Where(esc => esc.StandardId == es.StandardId).Distinct().Count(),
PostIdCount = db.EduStandardPosts.Where(esp => esp.StandardId == es.StandardId).Distinct().Count()
};
Also, I can't attest to the performance of either one of these queries due to the lack of knowledge of your database.
I'm stumped trying to convert the following sql to linq:
SELECT t.* FROM(SELECT mwfieldid,MAX([TimeStamp]) AS MaxValue, BatchDocumentID
FROM mw_BatchField
GROUP BY mwfieldid,BatchDocumentID) x
JOIN mw_BatchField t ON x.mwfieldid = t.mwfieldid
AND x.MaxValue = t.TimeStamp
and x.BatchDocumentID = t.BatchDocumentID
So far I had to convert it to a stored proc to get it to work. I'd rather know how to write this correctly in linq. I tried using a sql to linq converter (http://www.sqltolinq.com/) which produced this code that had errors in it: (Are these converters any good? It didn't seem to produce anything useful with a few tries.)
From x In (
(From mw_BatchFields In db.mw_BatchFields
Group mw_BatchFields By
mw_BatchFields.MWFieldID,
mw_BatchFields.BatchDocumentID
Into g = Group
Select
MWFieldID,
MaxValue = CType(g.Max(Function(p) p.TimeStamp),DateTime?),
BatchDocumentID)
)
Join t In db.mw_BatchFields
On New With { .MWFieldID = CInt(x.MWFieldID), .MaxValue = CDate(x.MaxValue), .BatchDocumentID = CInt(x.BatchDocumentID) }
Equals New With { .MWFieldID = t.MWFieldID, .MaxValue = t.TimeStamp, .BatchDocumentID = t.BatchDocumentID }
Select
BatchFieldID = t.BatchFieldID,
BatchDocumentID = t.BatchDocumentID,
MWFieldID = t.MWFieldID,
TimeStamp = t.TimeStamp,
value = t.value,
DictionaryValue = t.DictionaryValue,
AutoFilled = t.AutoFilled,
employeeID = t.employeeID
Seems like a lot of code for such a simple query, and it doesn't compile.
So for every combination of mwfieldid and BatchDocumentID you want all columns of the row with the highest TimeStamp? This is something which is much easier to express in LINQ than SQL so I'm not surprised that an automated converter is making a meal of it.
You should be able to do:
Mw_BatchFields.GroupBy(x => new { x.Mwfieldid, x.BatchDocumentId })
.SelectMany(x => x.Where(y => y.TimeStamp == x.Max(z => z.TimeStamp)))
This (like your SQL) will return multiple rows per grouping key if there is more than one row in the group that shares the same maximum TimeStamp. If you only want row per key, you could use:
Mw_BatchFields.GroupBy(x => new { x.Mwfieldid, x.BatchDocumentId })
.Select(x => x.OrderByDescending(y => y.TimeStamp).First())
Edit:
Sorry, just twigged that you're working in VB, not C#, so not quite what you were looking for, but if you can live with the lambda syntax style, I think the above can be translated as:
Mw_BatchFields.GroupBy(Function(x) New With {x.Mwfieldid, x.BatchDocumentId}).Select(Function(x) x.OrderByDescending(Function(y) y.TimeStamp).First())
and:
Mw_BatchFields.GroupBy(Function(x) New With {x.Mwfieldid, x.BatchDocumentId}).SelectMany(Function(x) x.Where(Function(y) y.TimeStamp = x.Max(Function(z) z.TimeStamp)))
I'm not good with LINQ yet and could use some help with the syntax.
Thanks!
The below query needs to be written in LINQ for C#.
SELECT Galleries.GalleryTitle, Media.*
FROM Galleries
INNER JOIN Media ON Galleries.GalleryID = Media.GalleryID
WHERE (Galleries.GalleryID = 150)
ORDER BY MediaDate DESC, MediaID DESC
Or with query syntax:
var query = from g in db.Galleries
join m in db.Media on g.GalleryID equals m.GalleryID
where g.GalleryID == 150
orderby m.MediaDate descending, m.MediaID descending
select new { g.GalleryTitle, Media = m };
Something like this:
var query = db.Galleries
.Join(db.Media, g => g.GalleryID, m => m.GalleryID, (g, m) => new {g, m})
.Where(r.g.GalleryID == 150)
.Select(res => new {res.g.GalleryTitle, Media = res.m}
.OrderByDescending(o => o.Media.MediaDate)
.ThenByDescending(o => o.Media.MediaID);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Equivalent of SQL ISNULL in LINQ?
Using IsNull or select COALESCE in Linq..?
I've tried this query in LINQ:
string query = #"SELECT ISNULL(P.firstname, s.firstname) AS Expr1,ISNULL(P.lastname,
s.lastname) AS Expr2 FROM comment AS C LEFT OUTER JOIN professor AS P ON P.ID =
C.PID LEFT OUTER JOIN student AS s ON s.ID = C.SID
WHERE (C.VID = 2)";
ArrayList allNames=null;
using (var context = new NewsReaderEntities())
{
ObjectQuery<string> results = context.CreateQuery<string>(query);
// ObjectQuery<string> results1 = context.CreateQuery<string>
(query1,parameters);
foreach (string result in results )
{
allNames.Add(result);
}
}
return allNames;
}
but it returns the error:
linq 'ISNULL' cannot be resolved into a valid type or function. Near
simple identifier,
I've also tried this query:
SELECT COALESCE(p.firstname, s.firstname), COALESCE(p.lastname, s.lastname)
FROM comment c
LEFT JOIN Professor p
ON c.pid = p.id
LEFT JOIN Student s
ON c.sid = s.id
WHERE c.vid = 2
This also raises an error.
Both work okay in SQL Management. Any ideas?
See this example:
var query = from p in Pets select p;
if (OwnerID != null) query = query.Where(x => x.OwnerID == OwnerID);
if (AnotherID != null) query = query.Where(x => x.AnotherID == AnotherID);
if (TypeID != null) query = query.Where(x => x.TypeID == TypeID);
Hope this help you