LINQ statement with conditional selection from table - linq

I am new to linq so I apologize in advance if it a dumb question. I inherited the following query and it is not producing correct results in order to fix it I have to understand what it is doing.
Here is the query, if someone can explain it to me what it is doing (also possibly fix it) that will be greatly appreciated.
**using (var dbCtx = new TLMDbContext())
{
var dvps = dbCtx.tblDVPTests.Where(x => x.DVPID == 2176);
// these 2 following if conditions doesnt bring correct result sets
if (dvpMasterPhaseId.HasValue)
{
dvps = dvps.Where(x => x.tblDVPPhases.All(p => p.DVPMasterPhaseID ==255));
}
if (dvpMasterVariantId.HasValue)
{
dvps = dvps.Where(x => x.tblDVPPhases.All(p => p.tblDVPVariants.All(v=>v.DVPMasterVariantID==681)));
}
}**
UPDATE
I want this following query to be written in LINQ and if one of you guys tell me what was wrong with the LINQ query above that will be great.
select * from tblDVPTest
inner join tblDVPPhase on tblDVPTest.DVPTestID=tblDVPPhase.DVPTestID
where dvpid=2176 and tblDVPPhase.DVPMasterPhaseID=255
Here is with both condition
select * from tblDVPTest
inner join tblDVPPhase on tblDVPTest.DVPTestID=tblDVPPhase.DVPTestID
inner join tblDVPVariant on tblDVPPhase.DVPPhaseID=tblDVPVariant.DVPPhaseID
where dvpid=2176 and tblDVPPhase.DVPMasterPhaseID=255 and tblDVPVariant.DVPMasterVariantID=681

As I can understand from code, you are using entity framework to interact with database. Below is a high level explanation:
Create DbContext object.
Select everything from table tblDVPTests into variable dvps where column DVPID of table tblDVPTests matches value of variable dvpNum.
If nullable variable dvpMasterPhaseId is not null then select only those values from dvps where referenced table tblDVPPhases has all rows with column DVPMasterPhaseID value matching with variable dvpMasterPhaseId value. Store result in dvps. If variable dvpMasterPhaseId is null skip this step.
If nullable variable dvpMasterVariantId is not null then select only those values from dvps where referenced table tblDVPPhases has all rows with column DVPMasterVariantID value matching with variable dvpMasterVariantId value. Store result in dvps. If variable dvpMasterVariantId is null skip this step.
Dispose DbCOntext object.
Note: There is a foreign key relationship between table tblDVPTests and tblDVPPhases.
To fix your issue first of all you should let us know what exactly you are expecting in the result.

Related

LINQ select column(s) of table before doing multiple joins

After running the query below and hovering over "usersToWork" when debugging, I can view all of the properties of the single entry that I get returned to me in addition to the other tables that have relations to this value. What I need to display to the user is the "Lines.Id" (Lines being the table and Id being the column in the Lines table) value, however that value gets lost from the SelectMany() statements. Is there anyway to select that "Lines.Id" value to include in the final value that I get from all of my joins? In the code below, I commented out what I want but I can't place that there otherwise I get error on the first SelectMany statement saying 'int' does not contain a definition for 'Shifts' and no extension method 'Shifts' accepting a first argument of type 'int' could be found.'
Correct me if I'm wrong but SelectMany() selects all of the columns from what you want to join on. In this case, in the first SelectMany() I get only values from the "Shifts" table and in the second SelectMany() I get only values from the "Users" table. Why is this different from the SQL join? When joining in SQL you can get every column as you join them together, SelectMany() yields only the values of the second table that you are joining on. Is it even possible to get that value in the "Lines" table or will I have to do another query? Any help would be great.
int idEnteredByUser = 123;
var usersToWork = entityDataModel.Lines
//....NOT IN MY CODE NOW....
// .Select(line => line.Id)//THIS IS WHAT I NEED.
// .Select(line => line.Description, line.Id//OR THIS TO RETURN TWO VALUES IF POSSIBLE
//This is my current code, I need to include on of the select lines above.
.SelectMany(line => line.Shifts) //Join lines on shifts.
.Where(shift => shift.EndTime >= DateTime.Now) //Join restricted times.
.SelectMany(user => user.Users) //Join the restricted shift times on users.
.Where(user => user.UserId == idEnteredByUser ); //Only look for the specific user
This works much easier using LINQ query syntax.
I'm assuming that you made a typo in your posted code and that user is a property of shift.
var idEnteredByUser = 123;
var usersToWork =
from line in entityDataModel.Lines
from shift in line.Shifts
where shift.EndTime >= DateTime.Now
from user in shift.Users
where user.UserId == idEnteredByUser
select new
{
Description = line.Description,
Id = line.Id
};

Dynamic Linq on DataTable error: no Field or Property in DataRow, c#

I have some errors using Linq on DataTable and I couldn't figure it out how to solve it. I have to admit that i am pretty new to Linq and I searched the forum and Internet and couldn't figure it out. hope you can help.
I have a DataTable called campaign with three columns: ID (int), Product (string), Channel (string). The DataTable is already filled with data. I am trying to select a subset of the campaign records which satisfied the conditions selected by the end user. For example, the user want to list only if the Product is either 'EWH' or 'HEC'. The selection criteria is dynaically determined by the end user.
I have the following C# code:
private void btnClick()
{
IEnumerable<DataRow> query =
from zz in campaign.AsEnumerable()
orderby zz.Field<string>("ID")
select zz;
string whereClause = "zz.Field<string>(\"Product\") in ('EWH','HEC')";
query = query.Where(whereClause);
DataTable sublist = query.CopyToDataTable<DataRow>();
}
But it gives me an error on line: query = query.Where(whereClause), saying
No property or field 'zz' exists in type 'DataRow'".
If I changed to:
string whereClause = "Product in ('EWH','HEC')"; it will say:
No property or field 'Product' exists in type 'DataRow'
Can anyone help me on how to solve this problem? I feel it could be a pretty simple syntax change, but I just don't know at this time.
First, this line has an error
orderby zz.Field<string>("ID")
because as you said, your ID column is of type int.
Second, you need to learn LINQ query syntax. Forget about strings, the same way you used from, orderby, select in the query, you can also use where and many other operators. Also you'll need to learn the equivalent LINQ constructs for SQL-ish things, like for instance IN (...) is mapped to Enumerable.Contains etc.
With all that being said, here is your query
var productFilter = new[] { "EWH", "HEC" };
var query =
from zz in campaign.AsEnumerable()
where productFilter.Contains(zz.Field<string>("Product"))
orderby zz.Field<int>("ID")
select zz;
Update As per your comment, if you want to make this dynamic, then you need to switch to lambda syntax. Multiple and criteria can be composed by chaining multiple Where clauses like this
List<string> productFilter = ...; // coming from outside
List<string> channelFilter = ...; // coming from outside
var query = campaign.AsEnumerable();
// Apply filters if needed
if (productFilter != null && productFilter.Count > 0)
query = query.Where(zz => productFilter.Contains(zz.Field<string>("Product")));
if (channelFilter != null && channelFilter.Count > 0)
query = query.Where(zz => channelFilter.Contains(zz.Field<string>("Channel")));
// Once finished with filtering, do the ordering
query = query.OrderBy(zz => zz.Field<int>("ID"));

LINQ delima to convert sql into LINQ

I am new to linq so I apologize in advance if it a dumb question. I inherited the following query and it is not producing correct results in order to fix it I have to understand what it is doing.
Here is the query.
using (var dbCtx = new TLMDbContext())
{
var dvps = dbCtx.tblDVPTests.Where(x => x.DVPID == 2176);
// these 2 following if conditions doesnt bring correct result sets
if (dvpMasterPhaseId.HasValue)
{
dvps = dvps.Where(x => x.tblDVPPhases.All(p => p.DVPMasterPhaseID ==255));
}
if (dvpMasterVariantId.HasValue)
{
dvps = dvps.Where(x => x.tblDVPPhases.All(p => p.tblDVPVariants.All(v=>v.DVPMasterVariantID==681)));
}
}
UPDATE
I want this following query to be written in LINQ and if one of you guys tell me what was wrong with the LINQ query above that will be great.
Following expression
dvps = dvps.Where(x => x.tblDVPPhases.All(p => p.DVPMasterPhaseID ==255));
Should be equivalent to this SQL Query.
select * from tblDVPTest
inner join tblDVPPhase on tblDVPTest.DVPTestID=tblDVPPhase.DVPTestID
where dvpid=2176 and tblDVPPhase.DVPMasterPhaseID=255
Here is with both condition
** LINQ**
dvps = dvps.Where(x => x.tblDVPPhases.All(p => p.tblDVPVariants.All(v=>v.DVPMasterVariantID==681)));
Should be equivalent to this SQL Query.
select * from tblDVPTest
inner join tblDVPPhase on tblDVPTest.DVPTestID=tblDVPPhase.DVPTestID
inner join tblDVPVariant on tblDVPPhase.DVPPhaseID=tblDVPVariant.DVPPhaseID
where dvpid=2176 and tblDVPPhase.DVPMasterPhaseID=255 and tblDVPVariant.DVPMasterVariantID=681
This code is adding two conditional filters (where) to the original query. Each extra filter limits the items included in the result.
In case the variable dvpMasterPhaseId is non-null the query only includes the items for which All related DPVPhases have a dvpMasterVariantId of 255
If the variable dvpMasterVariantId is non-null the query only includes the items for which All the related Variants of All the related Phases have a DVPMasterVariantID of 681.
The SQL code will not just show the DPV Tests for which ALL Phases / Variants meet these conditions, but where ANY of the Phases / Variants meet these conditions. Moreover it will return a separate row for each Test / Phase / Variant that meets these conditions

Dynamic Linq GroupBy Select not working properly

please guide, i am able to work with Dynamic Group by , but when selecting non agrigated fields , i get the following error
No property or field 'name' exists in type 'IGrouping`2'
var result311 = (IQueryable)gle1.temptable.Where(a => a.IsAllowed == false && a.Code == "r01");
var result = result311.GroupBy("new (name, FirstAmountOriginal, SecondAccounting)", "it")
.Select("new (it.name,Sum(FirstAmountOriginal) as FirstAmountOriginalx, Sum(SecondAccounting) as SecondAccountingx)");
Please guide
Firstly, you should not group by the fields you want to aggregate and secondly, the grouping creates a grouping Key consisting of the fields you group by (in this case one), so you must address this key afterwards:
var result = result311.GroupBy("new(name)", "it")
.Select(#"new (it.Key.name,
Sum(FirstAmountOriginal) as FirstAmountOriginalx,
Sum(SecondAccounting) as SecondAccountingx)");

linq where clause problem on multiple join tables

var studentDetails = from aspUser in db.aspnet_Users
join aspMembership in db.aspnet_Memberships on
aspUser.UserId equals aspMembership.UserId
join expUser in db.explore_users on
aspUser.UserId equals expUser.aspnetUserId
where expUser.Id.Equals(studID)
select new { expUser.DOB,
aspMembership.Email,
aspUser.UserName,
aspUser.LoweredUserName,
expUser.Id };
gv1.DataSource = studentDetails;
gv1.DataBind();
I have no idea why this did not work. When i remove where clause everything is running.
I have try to put where expUser.Id == studID is also did not work
if anyone can help me pls
Shouldn't that be where expUser.aspnetUserId.Equals(studID)?
If ID is the correct column then (as already commented) of what type are expUser.ID and the variable studID? Are they of the same type? If so then does the studID value exist in db.explore_users?

Resources