How do I change SQL Left Join to Lambda expression in C#? - c#

I have three tables and one input value. As a first step, based on the #Input, I need to fetch DSType from DSTypes table. Now again I need to compare DSType of DSTypes with RTInput table's IType column value. If RTInput table has matching records then need to fetch the ID column value alone otherwise NULL should be assigned.
I achieved this logic in SQL but unable to achieve the same in Lambda expression.
I tried some code from google but that is not returning correct value.
DECLARE #ID
#ID = SELECT ID FROM DSMaster Where DSTId = #Input
SELECT RTI.ID FROM DSTypes(NOLOCK) DST
LEFT JOIN RTInput(NOLOCK) RTI
ON RTRIM(LTRIM(DST.DSType)) = RTRIM(LTRIM(RTI.IType))
WHERE DST.ID = #ID
Lambda expression which I tried:
using (BEContext beContext = new BEContext())
{
var mData = beContext.DSMaster.Where(r => r.DSTId = inputvalue);
var Id = beContext.RTInput.Join(beContext.DSTypes.Where(dst => dst.ID == mData.Id )).Select(z => z.ID).FirstOrDefault();
}

I think this may help.
using {BEContext beContext = new BEContext()){
var mData = (from p in beContext.DSMaster.Where(r=>r.DSTId == inputvalue)
join pr in beContext.RTInput on p.Id equals dst.ID
select new {
//select what you want
}).FirstOrDefault();

Related

Grouping on virtual (predefined) column in linq

I am trying to write a linq query for one of my dashboard which retrieves data based on some conditions. I want to display records count based on the different status available in my table.
Following is the SQL query in which I am trying to convert into Linq.
select count(id) cnt, 'Available' label from table where date = sysdate
Above query is returning below result in DB IDE. This is the result I want with linq
cnt label
0 Available
I've tried with following linq query but it is returning 0 count and hence result is not being retrieved.
var data = (from a in context
where a.date = System.DateTime.Now
group a in a.id into g
select new {
cnt = g.Count(),
label = 'Available'
}).ToList();
How do I achieve above mentioned result in linq. Your help will be appreciated.
Thanks
-------------EDIT----------------
Updated LINQ query
var data = (from a in context.TableA
where a.id = uniqueID
group a in a.id into g
select new {
cnt = g.Count(),
label = 'Available'
}).Concat(from a in context.TableB
where a.id = uniqueID
group a in a.id into g
select new {
cnt = g.Count(),
label = 'WIP'
}).ToList();
To count the number of elements matching a predicate in a linq query simply use the where clause:
var results =
from a in context
where a.date.Date == DateTime.Now.Date
&& a.id == someIdHere
select a;
var data = new {
count = results.Count(),
label = "Available"
};
Or, in extension method syntax (which I prefer):
var results = context.Where(a => a.date.Date == DateTime.Now.Date && a.id == someIdHere);
var data = new {
count = results.Count(),
label = "Available"
};
Also be careful when comparing a DateTime object with regards to what results you desire; comparing DateTime.Now to a date will likley return false since it will compare the time code as well, use the DateTime.Date property to obtain only the date from the object for the purposes of comparison.

unable to create a constant value of type anonymous type only primitive types

Using Entity Framework Version=6.0.0.0 to get to get common id and orderid as shown below.
var dt1 = from p in dt.AsEnumerable()
select new
{
Id = p.Field<int>("Id"),
OrderId = p.Field<int>("OrderId")
};
var dt2 = (from order in db.Orders
select new
{
order.Id,
order.OrderId
}).ToList();
var intersect = dt1.Intersect(dt2);
Based on the list of values in intersect. I need to select all the values from Orders Table.
Trying to used code getting error "unable to create a constant value of type anonymous type only primitive types"
var result= (from a in sync.Orders
where intersect.Any(b => a.Id == b.Id && a.OrderId == b.OrderId)
select a).ToList();
You are trying to "join" an EF query with an in-memory data set, which does not work because there's not a way to embed the list and the lookup in SQL. One option is to pull the entire table into memory with AsEnumerable:
var result= (from a in sync.Orders.AsEnumberable
where intersect.Any(b => a.Id == b.Id && a.OrderId == b.OrderId)
select a).ToList();
Another option is to concatenate the Id and OrderId into one value and use Contains since that can be translated to an IN clause in SQL:
var lookup = intersect.Select(i => i.Id + "-" + i.OrderId).ToList();
var result= (from a in sync.Orders
where lookup.Contains(a.Id + "-" + a.OrderId)
select a).ToList();

linq-to-sql conditional read

I'm writing a query that looks like this:
var TheOutput = (from x in MyDC.MyTable
where.....
select new MyModel()
{
MyPropID = (from a in MyDC.MyOtherTable
where....
select a.ElementID).SingleOrDefault(),
MyPropData = (from a in MyDC.MyOtherTable
where a.ElementID == MyPropID
select a.ElementData).SingleOrDefault(),
}
I'm filling up MyModel with several properties from the database. Two of these properties are filled by reading another table. At the moment, I first read MyPropID to see if there's an element in the other table and then I read the other table again to get the data, regardless of whether or not an ID was retrieved.
How can I eliminate this second read if I know, from reading MyPropID and returning a null, that there's no data that matches the where a.ElementID == MyPropID clause.
Thanks.
var TheOutput = (from x in MyDC.MyTable
where.....
let id = (from a in MyDC.MyOtherTable
where....
select a.ElementID).SingleOrDefault()
select new MyModel()
{
MyPropID = id,
MyPropData = (from a in MyDC.MyOtherTable
where id != null && a.ElementID == id
select a.ElementData).SingleOrDefault()
}
If your code would create a single SQL statement from this query I do not think checking for null would matter. If this query would result in multiple SQL statements it might.

Entity Framework Query with MAX

I've been banging my head against the wall trying to translate a simple SQL Query into EF query..
Can anyone help please.. Following is the query I am trying to translate.
SELECT p.[UniqueId]
,p.[CAI]
,p.[HRGuid]
,p.[FullName]
,p.[Email]
,a.*
FROM [Participant] p
INNER JOIN
(
Select * FROM Assignment where assignmentNumber =
(Select MAX(AssignmentNumber)FROM
Assignment GROUP BY UniqueId)
) a
ON p.UniqueId = a.UniqueId
Basically I'm trying to get Participant along with their latest assignment.
You will need to create your Participant entity using Linq-Objects. You need to customize after AsEnumerable in order to create your entities
var query = (from p in context.Participant
join a in context.Assignment on p.UniqueId equals a.UniqueId into ag
select new
{
Participant = p,
Assignment = ag.OrderByDescending(x => x.AssignmentNumber).FirstOrDefault()
}).AsEnumerable()
.Select(x => new Participant(x.Participant )
{
Assignments = new Assignment[] { x.Assignment }
};

GridView and Linq Query sorting

I'm using a Linq Query to populate a GridView.
Then I set it to the Datasource.
In the sorting event, I'd like to retrieve the the anonymous type that the query generates and find the members name.
Is it possible to do so ?
Here's an exemple of the query
var q = from inboundCall in dc.GetTable<InboundCall>()
join employee in dc.GetTable<Employee>() on inboundCall.EmployeeID equals employee.ID
join code in dc.GetTable<Code>() on inboundCall.CodeID equals code.ID
join site in dc.GetTable<Site>() on inboundCall.SiteID equals site.ID
where inboundCall.IsSuccess == true
select new
{
EmployeeNumber = employee.Number,
EmployeeName = employee.Name,
CallerID = inboundCall.CallerID,
SiteName = site.Name,
CallDate = inboundCall.CallDate,
CodeName = code.Name
};
And then
gridData.DataSource = q;
What can I do in the sorting event to retieve the Anonymous type and do something like that
employeeList.Sort((x, y) => ((Int32)x.GetType().GetProperty(e.SortExpression).GetValue(x, null)).CompareTo((Int32)y.GetType().GetProperty(e.SortExpression).GetValue(y, null)) * sortValue);
You could do this with reflection, or you could use the dynamic LINQ library to add the OrderBy clause.
Or, a better option may be to create an actual class / struct that represents the data you will be retrieving.

Categories