Get linq to return IEnumerable<DataRow> result - c#

How can I convert following SQL query to LINQ in C#?
I don't need all columns from both tables and the result set should be
IEnumerable<DataRow>
Query:
select
c.level, cl.name, c.quantity
from
dbo.vw_categories c
left join
dbo.vw_categoriesLocalization cl on c.level = cl.level
and cl.language = 'en'
where
c.level like '000%'
and c.level <> '000';
Expected:
IEnumerable<DataRow> result = ????
Thanks in advance..

Here's how you would write the query:
var query =
from c in db.vw_categories
join cl in db.vw_categoriesLocalization on c.level equals cl.level into clo
from cl in clo.DefaultIfEmpty()
where (cl == null || cl.language == "en")
&& c.level.StartsWith("000")
&& c.level != "000"
select new
{
c.level,
name = cl == null ? null : cl.name,
c.quantity
}
To convert that to IEnumerable<DataRow> maybe you could do something like this:
var datarows = query.Select(r => {
var row = dataTable.NewRow();
row["level"] = r.level;
row["name"] = r.name;
row["quantity"] = r.quantity;
return row;
});

If using LINQ to SQL:
var ctx = new SomeDataContext();
from c in ctx.vw_categories
join cl in ctx.vw_categoriesLocation
on c.level equals cl.level into g
from clv in g.DefaultIfEmpty()
where (clv == null || clv.language == "en")
&& c.level.Contains("000%")
&& c.level != "000"
select new
{
c.level,
name = (clv != null) ? clv.name : default(string),
quantity = c.quantity
};
More info here: http://codingsense.wordpress.com/2009/03/08/left-join-right-join-using-linq/

Related

How to create Linq Query between a dataTable and a Sql Table

I have a DataTable and a SQLTable . I want to write a linq Qurty to create a result that has Information from both tables. I wrote this code. but it runs very slowly. How can I optimize it?
var Result = (from DataRow row in dTable.Rows
from obj in db.SQLTable
where (
obj.Status != "Suspend" &&
(
(obj.Type.ToLower() == "a" && obj.Code ==
row[2].ToString()) ||
(obj.Type.ToLower() == "b" &&
obj.Code.Substring(6) == row[2].ToString())
)
select new
{
ID = obj.ID,
RowNum = row[0],
}).ToList();
I'm not sure if this is 100% the correct syntax.
The idea here is that we select calculated columns to join against. That way we're calculating the obj.Type.ToLower() and obj.Code.Substring(6) once per row (n times), rather than once per join instance (n*m times).
var Result = (from DataRow row in dTable.Rows
from obj in (db.SQLTable).Select(x => new {x.Status, ObjTypeLower = x.Type.ToLower(), x.Code, ObjCodeSub = x.Code.Substring(6)})
where (
obj.Status != "Suspend" &&
(
(obj.ObjTypeLower == "a" && obj.Code ==
row[2].ToString()) ||
(obj.ObjTypeLower == "b" &&
obj.ObjCodeSub == row[2].ToString())
)
select new
{
ID = obj.ID,
RowNum = row[0],
}).ToList();
try something like this
var result=(from e in db.Users
select e.UserID).Except(from m in db.Fi
select m.UserID).ToList();

C# - Using Linq get data if null value exist in query

I have two datatables,
var userList1 = from myRow in dt.AsEnumerable()
where myRow.Field<bool?>("IsActive1") == null
? true
: myRow.Field<bool?>("IsActive1") == true
select myRow;
var userList2 = from myRow in dt1.AsEnumerable()
select myRow;
dt1 table shows like this,
Using this Linq query,
var objUserSetUp1 = (from A in userList1
join B in userList2
on new
{
UserId = A.Field<Int64?>("Id") == null
? 0
: A.Field<Int64>("Id")
}
equals new
{
UserId = B.Field<Int64?>("UserId") == null
? 0
: B.Field<Int64>("UserId")
}
select new
{
UserId = A.Field<Int64>("Id"),
FirstName = A.Field<string>("FirstName"),
SurName = A.Field<string>("SurName"),
Computer_Name = A.Field<string>("Computer_Name"),
IP_Address = A.Field<string>("IP_Address"),
LogInTime = A.Field<string>("LogInTime") == null
? "UnKnown"
: A.Field<string>("LogInTime"),
UserName = A.Field<string>("UserName"),
Password = A.Field<string>("Password"),
login_Id = A.Field<Int64?>("login_Id") == null
? 0 :
A.Field<Int64?>("login_Id"),
docCount = B.Field<Int64>("docCount")
}).ToList();
How can I get if UserId is null also want to take docCout field value too. How can I do this inside the query?
I think you need a Left Outer Join, where the default value for the outer join (ie when no matching record exists) is the userList2 entry where Field("UserId") is null.
See below (untested, but you get the idea!):
var objUserSetUp1 = (from A in userList1
join B in userList2
on A.Field<Int64?>("Id") equals B.Field<Int64?>("UserId")
into BGroup
from C in BGroup.DefaultIfEmpty(userList2.Single(u => u.Field<Int64?>("UserId") == null))
select new
{
UserId = A.Field<Int64>("Id"),
FirstName = A.Field<string>("FirstName"),
SurName = A.Field<string>("SurName"),
Computer_Name = A.Field<string>("Computer_Name"),
IP_Address = A.Field<string>("IP_Address"),
LogInTime = A.Field<string>("LogInTime") == null
? "UnKnown"
: A.Field<string>("LogInTime"),
UserName = A.Field<string>("UserName"),
Password = A.Field<string>("Password"),
login_Id = A.Field<Int64?>("login_Id") == null
? 0 :
A.Field<Int64?>("login_Id"),
docCount = C.Field<Int64>("docCount")
}).ToList();

Getting Column Value from another Subquery

I have a LINQ query. But I need to get value of two columns from another subquery. This is my Linq query:
)from t in db.PUTAWAYs
join t0 in db.ASN_ITEM on t.AWB_NO equals t0.AWB_NO
join t1 in db.ASN_MASTER on t0.AWB_NO equals t1.AWB_NO
join t2 in db.ITEM_MASTER on t.ITEM_MASTER.ITEM_CODE equals t2.ITEM_CODE
join t3 in db.ASN_INPUT on t0.AWB_NO equals t3.AWB_NO
where
t3.ITEM == t2.ITEM_CODE &&
1 == 1 &&
(fromDate == "" || toDate == "" || (t0.REC_DATE.CompareTo(fromDate) >= 0 && t0.REC_DATE.CompareTo(toDate) <= 0)) &&
(AWB_NO == "" || (t0.AWB_NO == AWB_NO))
orderby
t.AWB_NO,
t0.REC_DATE,
t0.STYPE,
t2.PART_NO
select new ASNPutawayRep
{
AWB_NO = t.AWB_NO,
REC_DATE = t0.REC_DATE,
STYPE = t0.STYPE,
PART_NO = t2.PART_NO,
//LOCATION_AD = t.LOCATION_AD,
QNTY = t.QNTY,
//LOCATION_SD = t.LOCATION_SD,
REGION_ID = t.REGION_ID
}).Distinct();
Here in select portion of above query, instead of directly taking value of the column t.LOCATION_AD, I need to get it from SELECT LOC_NAME FROM LOCATION_MASTER WHERE LOC_CODE = t.LOCATION_AD
and instead of t.LOCATION_SD, I need to get value from SELECT LOC_NAME FROM LOCATION_MASTER where LOC_CODE = t.LOCATION_SD
How can I write this in LINQ. Is there any way to do this?
You can make use of let clause. It is useful to store the result of sub-expression in order to use it in subsequent clauses.
Example:
(from t in db.PUTAWAYs
...
let locAd = from l in LOCATION_MASTER where LOC_CODE = t.LOCATION_SD select l.LOC_NAME
where
...
orderby
...
select new ASNPutawayRep
{
LOCATION_AD = locAd,
}).Distinct();
Also, you can directly write LINQ without using let clause:
(from t in db.PUTAWAYs
...
where
...
orderby
...
select new ASNPutawayRep
{
LOCATION_AD = from l in LOCATION_MASTER where LOC_CODE = t.LOCATION_SD select l.LOC_NAME
}).Distinct();
You can use AsQueryable to achieve this
from t in db.PUTAWAYs
join t0 in db.ASN_ITEM on t.AWB_NO equals t0.AWB_NO
join t1 in db.ASN_MASTER on t0.AWB_NO equals t1.AWB_NO
join t2 in db.ITEM_MASTER on t.ITEM_MASTER.ITEM_CODE equals t2.ITEM_CODE
join t3 in db.ASN_INPUT on t0.AWB_NO equals t3.AWB_NO
where
t3.ITEM == t2.ITEM_CODE &&
1 == 1 &&
(fromDate == "" || toDate == "" || (t0.REC_DATE.CompareTo(fromDate) >= 0 && t0.REC_DATE.CompareTo(toDate) <= 0)) &&
(AWB_NO == "" || (t0.AWB_NO == AWB_NO))
orderby
t.AWB_NO,
t0.REC_DATE,
t0.STYPE,
t2.PART_NO
select new ASNPutawayRep
{
AWB_NO = t.AWB_NO,
REC_DATE = t0.REC_DATE,
STYPE = t0.STYPE,
PART_NO = t2.PART_NO,
LOCATION_AD = (from l in db.LOCATION_MASTER
where l.LOC_CODE = t.LOCATION_AD
select LocName)ToList().FirstorDefault(),
QNTY = t.QNTY,
LOCATION_SD = (from l in db.LOCATION_MASTER
where l.LOC_CODE = t.LOCATION_SD
select LocName).ToList().FirstorDefault(),
REGION_ID = t.REGION_ID
}).Distinct();

Union Two Linq Queries

I have two LinqToSql queries that return result sets:
var grResults = (from g in ctx.GeneralRequests
join rt in ctx.RequestTypes on g.RequestTypeId equals rt.RequestTypeId
join sub in ctx.Logins on g.SubmitterStaffId equals sub.LoginId
join onb in ctx.Logins on g.OnBehalfOfStaffId equals onb.LoginId
where sub.GadId == gadId
select new
{
Status = "Submitted",
RequestId = g.GeneralRequestId,
Submitter = sub.UserName,
OnBehalf = (onb == null ? string.Empty : onb.UserName),
RequestType = (rt == null ? string.Empty : rt.Description),
ProjectName = (g == null ? string.Empty : g.ProjectName) ,
Comments = (g == null ? string.Empty : g.Comments),
LastUpdate = g.LastUpdateDate
});
var grdResults = (from gd in ctx.GeneralRequestDrafts
join rt in ctx.RequestTypes on gd.RequestTypeId equals rt.RequestTypeId
into tempRequestTypes
from rt1 in tempRequestTypes.DefaultIfEmpty()
join onb in ctx.Logins on gd.OnBehalfOfStaffId equals onb.LoginId
into tempOnBehalf
from onb1 in tempOnBehalf.DefaultIfEmpty()
join sub in ctx.Logins on gd.SubmitterStaffId equals sub.LoginId
where sub.GadId == gadId
select new
{
Status = "Draft",
RequestId = gd.GeneralRequestDraftId,
Submitter = sub.UserName,
OnBehalf = (onb1 == null ? string.Empty : onb1.UserName),
RequestType = (rt1 == null ? string.Empty : rt1.Description),
ProjectName = (gd.ProjectName == null ? string.Empty : gd.ProjectName),
Comments = (gd.Comments == null ? string.Empty : gd.Comments),
LastUpdate = gd.LastUpdateDate
});
The problem is when I try to Union them.
var results = grResults.Union(grdResults).OrderByDescending(r => r.LastUpdate);
This returns no records even though the two individual queries do.
Since the 2 queries don't appear to rely on each other just execute both and union the results of each if you are just trying to get a single list.
var results = grResults.ToList().Union(grdResults.ToList())
.OrderByDescending(r => r.LastUpdate);

c# Linq select join on select group by

I have this MS-SQL statement :
SELECT cv.id FROM ContactValue cv
INNER JOIN (
SELECT mainId, max(version) as v
FROM ContactValue
WHERE version <= $Version(int)
GROUP BY mainId
)
AS t ON t.mainId = cv.mainId AND t.v = cv.version
WHERE cv.contact_id = $ContactID(int)
AND cv.isActive = 1
ORDER BY sort'
and would like to make it in linq.
I did make above query divided into multiple queries witch performence is not fast.
Does it exist any linq to linq joining
My C# code :
var groupMax = from cv in db.ContactValue
where cv.contact_id == ContactID && cv.version <= Version
orderby cv.sort
group cv by cv.mainId into gcv
select new { mainID = gcv.Key, version = gcv.Max(cv => cv.version) };
foreach (var data in groupMax.ToList())
{
var Query = from cv in db.ContactValue
where cv.contact_id == ContactID && cv.mainId == data.mainID && cv.version == data.version && cv.isActive == true
select cv;
if (Query.Count() > 0)
{
ContactValue tmp = Query.First();
}
}
I would love to get all contacts with 1-2 queries not 1 query then for each contact another query...
Please help me !
Yes, Linq to SQL does have an inner join implemented:
var groupMax =
from cv in db.ContactValue
where cv.contact_id == ContactID && cv.version <= Version
orderby cv.sort
group cv by cv.mainId into gcv
select new { mainID = gcv.Key, version = gcv.Max(cv => cv.version) };
var res =
from cv in db.ContactValue
join gm in groupMax on cv.version equals gm.version
where cv.contact_id == ContactID && cv.isActive
orderby cv.version ascending /*for example*/
select cv
protected void rptPriceRachiveBind()
{
using (MyEntities ctx = new MyEntities())
{
var catRef = Convert.ToInt32(Request.QueryString["CategoryRef"]);
var prodCounts = (
from A in ctx.Products
join B in ctx.ProductPrices
on A.ProductId equals B.ProductRef
where A.CategoryRef == catRef
group A by new { A.Name,B.ProductRef } into catGp
select
new
{
catGp.Key.ProductRef,
catGp.Key.Name,
proIdCount = catGp.Count()
}).ToList();
Repeater1.DataSource = prodCounts;
Repeater1.DataBind();
}

Categories