I have a SQL query, which i know works as expected. But i need it to be LINQ which i use to interact with the database. The SQL query is:
SELECT * FROM motorposition, experimentmotor, motors
WHERE motorposition.motorid = experimentmotor.motorid
AND experimentmotor.experimentid = 13
AND motors.id = experimentmotor.motorid
I have almost no experience with LINQ. Is it even possible to do this in LINQ?
The code would be something like this:
var results = from mp in yourcontext.motorposition
join e in yourcontext.experimentmotor on mp.motorid equals e.motorid
join m in yourcontext.motors on e.motorid equals m.motorid
where e.experimentid == 13
select new {mp, e, m};
Related
I'm trying to join three tables together, but I just can't get my LINQ statements to get the data I want to. My SQL query that I want to replicate is like this:
SELECT TOP 5 SUM(Grade) AS 'TotalGrade', COUNT(Restaurants.Name) AS 'NumberOfVisits', Restaurants.Name FROM Lunches
JOIN dbo.LunchRestaurant ON Lunches.LunchId = LunchRestaurant.LunchId
JOIN Restaurants ON Restaurants.RestaurantId = LunchRestaurant.RestaurantId
GROUP BY Restaurants.Name
The LINQ statement I currently have is:
var q = from l in lunchContext.Lunches
join lr in lunchContext.LunchRestaurant on l.LunchId equals lr.LunchId
join r in lunchContext.Restaurants on lr.RestaurantId equals r.RestaurantId
select new { l.Grade, r.RestaurantId};
But with this one, I can't get in my group by statement or the aggregate functions no matter how I try. Do you have any suggestions on what to do? There also doesn't seem to be a way to write raw SQL statements when dealing with several tables, at least not easily done in EF Core if I'm not mistaken. Otherwise that'd be an option too.
I think you're looking for linq grouping. From memory, it would be something like;
var q = from l in lunchContext.Lunches
join lr in lunchContext.LunchRestaurant on l.LunchId equals lr.LunchId
join r in lunchContext.Restaurants on lr.RestaurantId equals r.RestaurantId
group l by lr.RestaurantId into g
select new { Id = g.Key, Grade =g.Sum(x=>x.Grade)};
If you do need to go down the raw SQL route then you can levarage ADO.Net like this
using (var command = lunchContext.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "{Your sql query here}";
context.Database.OpenConnection();
using (var result = command.ExecuteReader())
{
// do something with result
}
}
I have had an extensive look around on SE, tried all of the suggestions, checked out MSDN how to perform Left Join equivalent in LINQ to SQL and I have constructed my LINQ query according to MSDN example.
However, the result is not what SQL would return and I am completely lost as to where am I going wrong.
Here is some details:
I have two tables, Customers and Reports. A customer can submit many reports or none. In the current state I have many more reports than customers.
LINQ code:
var query = {from c in customers
join r in reports on c.Id equals r.Id into temp
from items in temp.DefaultIfEmpty()
select new {
c.Id,
LastReportDate = items?.DateCreated ?? DateTime.MinValue
}).ToList();
SQL code:
SELECT [Customers].[Id], R.LastReport AS LastReportDate FROM [Customers]
LEFT JOIN (
SELECT Reports.Id, MAX( [Reports].[Created] ) AS LastReport
FROM Reports GROUP BY Reports.Id
) AS r ON [Customers].[Id] = r.[Id]
The problem is that the query returns number of elements equal to number of reports. However, what I want is to get a list with all customers and for those who have submitted a report I wish to display the date of the most recent report, for those who have not submitted anything, I am happy to leave it NULL or DateTime.MinValue
Any help would be greatly appreciated. I guess I am missing a group by call somewhere in my LINQ code...
Im thinking probably something like this:
var query =
from c in customers
join r in reports on c.Id equals r.Id into g
select new
{
c.Id,
LastReportDate = g.Max(x => (DateTime?)x.Created)
};
you are now joining on join r in reports on c.Id equals r.Id into temp
this looks like: join on a customer.Id on Reports.Id, since you say there are 1 to many relation/rapport. I think your table will have a Reports.CustomerId. Is this correct?
So your query should something look like:
var results = customer.Where(c => c.Reports.Any())
.SelectMany(c => {c, c.Reports.Max(r => r.Created)})
.ToList();
the select comes out of my head, so i am probably missing something ;)
Have you tried LinqPad ? There you can type your linq-queries, and directly see your sql code and results. Works like a charm!
I have an issue with a c# linq query where I use the != operator, it works well in SQL but when I write the same query in C# it returns a different result, which is the correct way to the the results where table a column doesn't match table b column. Please see my sql query below and then my c# query.
SELECT tba.ID,fa.accountnumber,tba.Account_Number,fa.new_legalname,tba.Legal_Name,fa.new_deliverystatusname, fa.new_deliverystatus,tba.Delivery_Charge
FROM [CRM_Embrace_Integration].[dbo].[CRM_Tarsus_Debtors_Accounts] tba
inner join CRM_MBT_GROUP.dbo.FilteredAccount fa
ON fa.accountnumber collate database_default = tba.Account_Number
where fa.new_legalname collate database_default != tba.Legal_Name
and the Linq query looks like this
var sqlJoinQuery = from accCRM in todaysCRMAccounts
join accSQL in todaysCRMViewAccounts
on accCRM.Account_Number equals accSQL.accountnumber
where accCRM.Legal_Name != accSQL.new_legalname
select new { accCRM.Legal_Name, accSQL.new_legalname };
The SQL query returns the correct result as I want where legal_name(table A) is not equals to legal_name(table B) is the other table.
The Linq query return incorrect result, please assist.
I suggest to try the following Linq as you want the data that aren't in table 2:
var result1 = (from m in db1.Table1
select m).ToList();
var result2 = (from m in db2.Table2
select m).ToList();
var finalResult = (from m in result1
where !(from k in result2
select k.Id).Contains(m.Id)
select m).ToList();
The above will return that aren't in Table2. I hope, this is what you wanted.
Your SQL shows you asking for where they are equal. The LINQ shows you asking for when they are not equal.
I'm struggling with converting SQL query to LINQ
SELECT * FROM Log x
JOIN (SELECT p.objId,
MAX(modifiedDateTime) AS latestDateTime
FROM Log p
GROUP BY p.objId) y ON y.objId= x.objId
AND y.latestDateTime = x.modifiedDateTime
Please suggest. This is where I got so far
var query1 = from x in query
join y in query
on new {x.objId, x.modifiedDateTime}
equals new {y.objId, ...(Max)}
the two new anonymous objects you create won't ever be equal. You need to compare the values to one another directly. Try:
on x.objID equals y.objID && x.modifiedDateTime equals y.lastestDateTime
Is it posible in NHibernate to create a query that looks like this?
select hi.ContactId
From dbo.vw_HostInterests hi INNER JOIN
( Select cm1.ContactId
From dbo.vw_ContactMoments cm1 INNER JOIN
(
Select Contactid
From dbo.vw_ProfileNaw
where GenderId = 1000
) as pn1 on cm1.ContactId = pn1.ContactId
where cm1.ActivityId = 1001
)as cm on hi.ContactId = cm.ContactId
where hi.ActivityId = 1038
I've managed to create the correct output with the IN statement, but I'd realy like the SQL to look like this.
The Criteria below shows part of above query with the IN Statement I used (but want to replace):
ICriteria criteria = DbSession.CreateCriteria<Contact>();
var dCriteria1 = DetachedCriteria.For(typeof(VwHostInterest))
.Add(Expression.Eq("ActivityId", 1038))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContactId")));
var dCriteria2 = DetachedCriteria.For(typeof(VwContactMoment))
.Add(Expression.Eq("ActivityId", 1001))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContactId")));
criteria.Add(Subqueries.PropertyIn("ContactId", dCriteria1));
criteria.Add(Subqueries.PropertyIn("ContactId", dCriteria2));
int count = (Int32)criteria
.SetProjection(Projections.Count("ContactId"))
.UniqueResult();
Probably not the answer you are looking for and apologies if it isn't but my experience is that your best bet with such complex queries would be to:
a) Do this whole thing as a view and map it in NHibernate
b) Create the inner select as a view and create a mapping such that you can relate it in your query
b) Or override nhibernate (override as in skip and not in OO terms ;) and write this as a named query using native SQL.
Does that nested query produce the same result as the following?
SELECT hi.ContactId
FROM dbo.vw_HostInterests hi
INNER JOIN vw_ContactMoments cm1 on hi.ContactId = cm1.ContactId
AND cm1.ActivityId = 1001
INNER JOIN dbo.vw_ProfileNaw pn1 on pn1.ContactId = cm1.ContactId
AND pn1.GenderId = 1000
WHERE hi.ActivityId = 1038