Union Two Linq Queries - c#

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);

Related

What is the best way to display date time using Linq to Datatable?

I have a linq that select some column with dates to datatable.
I am using ASP MVC 5 and Datatble.
I really need the DateTime. I have displayed string and had no issues.
But when I try to display the raw date time I get this output
/Date(1569366000000)/ /Date(1569397607057)/
Here is my code
var IQueryabletimesheet = (from expense in _context.ExpenseModel
join expenseaudittb in _context.ExpenseAuditTB on expense.ExpenseID equals expenseaudittb.ExpenseID
join project in _context.ProjectMaster on expense.ProjectID equals project.ProjectID
join registration in _context.Registration on expense.UserID equals registration.RegistrationID
join AssignedRolesAdmin in _context.AssignedRoles on registration.RegistrationID equals AssignedRolesAdmin.RegistrationID
where AssignedRolesAdmin.AssignToAdmin == UserID && expenseaudittb.Status == 3
select new ExpenseModelView
{
ExpenseID = expense.ExpenseID,
ProjectName = project.ProjectName,
RequestBy = registration.Name,
FromDate = expense.FromDate.Value,
ProcessedDate = expenseaudittb.ProcessedDate,
ExpenseStatus = expense.ExpenseStatus == 1 ? "Submitted" : expense.ExpenseStatus == 2 ? "Approved" : expense.ExpenseStatus == 4 ? "Pending Final Approval" : "Rejected",
PurposeorReason = expense.PurposeorReason,
TotalAmount = expense.TotalAmount,
VoucherID = expense.VoucherID,
});
if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
{
IQueryabletimesheet = IQueryabletimesheet.OrderBy(sortColumn + " " + sortColumnDir);
}
if (!string.IsNullOrEmpty(Search))
{
//IQueryabletimesheet = IQueryabletimesheet.Where(m => m.FromDate == Search);
}
return IQueryabletimesheet;
I am getting the result via ajax call in the view. That has no issue, except for the datetime columns that display the above errors
I need something like what I see in my SQL Server
08/10/2019 10:43
I found a solution to my problem. Note, this may not be the only solution but does exactly what I want. The solution is using moment.js and this is how I rendered the column and everything worked. I wanted the data raw with its type (datetime) retained.
{
title: "ProcessedDate",// name
render: function (data, type, row)
{//data
return moment(row.ProcessedDate).format('DD/MM/YYYY hh:mm:ss');
}
}
To display as expected you have to do the date to string conversion. ex. string.Format ("{0: G}", expense.FromDate.Value).
var IQueryabletimesheet = (from expense in _context.ExpenseModel
join expenseaudittb in _context.ExpenseAuditTB on expense.ExpenseID equals expenseaudittb.ExpenseID
join project in _context.ProjectMaster on expense.ProjectID equals project.ProjectID
join registration in _context.Registration on expense.UserID equals registration.RegistrationID
join AssignedRolesAdmin in _context.AssignedRoles on registration.RegistrationID equals AssignedRolesAdmin.RegistrationID
where AssignedRolesAdmin.AssignToAdmin == UserID && expenseaudittb.Status == 3
select new ExpenseModelView
{
ExpenseID = expense.ExpenseID,
ProjectName = project.ProjectName,
RequestBy = registration.Name,
FromDate = string.Format ("{0:G}", expense.FromDate.Value),
ProcessedDate = expenseaudittb.ProcessedDate,
ExpenseStatus = expense.ExpenseStatus == 1 ? "Submitted" : expense.ExpenseStatus == 2 ? "Approved" : expense.ExpenseStatus == 4 ? "Pending Final Approval" : "Rejected",
PurposeorReason = expense.PurposeorReason,
TotalAmount = expense.TotalAmount,
VoucherID = expense.VoucherID,
});

EF Core Linq join on multiple columns throws NullReference Exception

I have a rather ugly query that just had to be expanded by one more join. The query builds then throws a NullReferenceException runtime. As I'm struggling around the exception details I found the message at TargetSite/CustomAttributes/Message = "The method or operation is not implemented." But I don't know which method?
MarkedItems is the new join and I think the problem could be the join on multiple columns or that I had to add the new table into the group by clause. The same query runs in LinqPad with EF6, so this must be something that hasn't been implemented in EF7 yet.
EF Core version is 1.1.2.
The query:
var inventory = (from it in _ctx.Items
join i in _ctx.Inventories on it.Id equals i.ItemId into iit
from i in iit.DefaultIfEmpty()
join m in _ctx.MarkedItems on
new {
eancode = i.EANCode,
projectid = i.ProjectId
}
equals new {
eancode = (m != null ? m.EANCode : string.Empty),
projectid = (m != null ? m.ProjectId : Guid.Empty)
} into im
from m in im.DefaultIfEmpty()
where it.ProjectId == cmp.ProjectId
group i by new {
EANCode = it.EANCode,
ItemNo = it.ItemNo,
Name = it.Name,
BaseQty = it.BaseQty,
Price = it.Price,
m = (m != null ? m.EANCode : null)
} into lg
select new ComparisonBaseModel() {
EANCode = lg.Key.EANCode,
ItemName = lg.Key.Name,
Price = lg.Key.Price,
ScanQty = lg.Sum(s => s != null ? s.ScanQty : 0),
BaseQty = lg.Key.BaseQty,
DiffQty = lg.Sum(s => s != null ? s.ScanQty : 0) - lg.Key.BaseQty,
DiffPrice = lg.Key.Price * (lg.Sum(s=> s!= null ? s.ScanQty : 0) - lg.Key.BaseQty),
AllTasked = !lg.Any(s=>(s != null && s.InventoryTaskId == null) || s==null),
Flagged = lg.Key.m != null
}).Where(x=>x.DiffQty != 0);
Thanks to the comments I was able to find out the real problem with my query. I hadn't realized before, that Inventories (i) could be null, too, so I had to check for nulls even the i-s (not only m-s) in MarketItems join.
Not sure if this could be helpful to anyone but the error message was misleading after I have already run into some EF7/EF6 differences.
var inventory = (from it in _ctx.Items
join i in _ctx.Inventories on it.Id equals i.ItemId into iit
from i in iit.DefaultIfEmpty()
join m in _ctx.MarkedItems on
new {
eancode = (i != null ? i.EANCode : string.Empty),
projectid = (i != null ? i.ProjectId : Guid.Empty)
}
equals new {
eancode = (m != null ? m.EANCode : string.Empty),
projectid = (m != null ? m.ProjectId : Guid.Empty)
} into im
from m in im.DefaultIfEmpty()
where it.ProjectId == cmp.ProjectId
group i by new {
EANCode = it.EANCode,
ItemNo = it.ItemNo,
Name = it.Name,
BaseQty = it.BaseQty,
Price = it.Price,
m = (m != null ? m.EANCode : null)
} into lg
select new ComparisonBaseModel() {
EANCode = lg.Key.EANCode,
ItemName = lg.Key.Name,
Price = lg.Key.Price,
ScanQty = lg.Sum(s => s != null ? s.ScanQty : 0),
BaseQty = lg.Key.BaseQty,
DiffQty = lg.Sum(s => s != null ? s.ScanQty : 0) - lg.Key.BaseQty,
DiffPrice = lg.Key.Price * (lg.Sum(s=> s!= null ? s.ScanQty : 0) - lg.Key.BaseQty),
AllTasked = !lg.Any(s=>(s != null && s.InventoryTaskId == null) || s==null),
Flagged = lg.Key.m != null
}).Where(x=>x.DiffQty != 0);

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();

linq subselect causing out of memory error

The Version field subselect in the where caluse is causing an out of memory error. If I remove it then the query works fine. The user profile table has multiple entries for each version and I only want the most recent in the final query results. Any ideas on how to make this query work without getting an out of memory error?
var x = (from p in userProfileRepo.All
join u1 in userRepo.All on p.USERID equals u1.USERID
join u2 in userRepo.All on p.LAST_MODIFIED_BY equals u2.USERID
join a in attrRepo.All on new { p.GROUP_NAME, p.PROFILE_NAME } equals new { a.GROUP_NAME, a.PROFILE_NAME } into attrJoin
from sub_a in attrJoin.DefaultIfEmpty()
where p.VERSION == (from up in userProfileRepo.All
where up.GROUP_NAME == p.GROUP_NAME
&& up.PROFILE_NAME == p.PROFILE_NAME
&& up.USERID == p.USERID
group up by up.VERSION into g
select g.Max(t => t.VERSION)).FirstOrDefault()
select new
{
GroupName = p.GROUP_NAME,
Author = u1.FIRSTNAME + #"\" + u1.LASTNAME,
LastModifiedBy = u2.FIRSTNAME + #"\" + u2.LASTNAME,
ProfileName = p.PROFILE_NAME,
Version = p.VERSION,
GroupName2 = (sub_a == null ? "" : sub_a.GROUP_NAME),
AttrName = (sub_a == null ? "" : sub_a.ATTR_NAME),
AttrDisplayName = (sub_a == null ? "" : sub_a.ATTR_DISPLAY_NAME),
AttrValue = (sub_a == null ? "" : sub_a.ATTR_VALUE),
Visible = (sub_a == null ? "" : sub_a.VISIBLE)
}).ToList();

Entity Framework - Handle null value in Linq

I'm writing two LINQ queries where I use my first query's result set in my second query.
But in some cases when there is no data in the database table my first query returns null,
and because of this my second query fails since wsdetails.location and wsdetails.worklocation are null causing an exception.
Exception:
Object reference not set to an instance of an object
My code is this:
var wsdetails = (from assetTable in Repository.Asset
join userAsset in Repository.UserAsset on
assetTable.Asset_Id equals userAsset.Asset_Id
join subLocationTable in Repository.SubLocation on
assetTable.Sub_Location_Id equals subLocationTable.Sub_Location_ID
where userAsset.User_Id == userCode
&& assetTable.Asset_TypeId == 1 && assetTable.Asset_SubType_Id == 1
select new { workstation = subLocationTable.Sub_Location_Name, location = assetTable.Location_Id }).FirstOrDefault();
result = (from emp in this.Repository.Employee
join designation in this.Repository.Designation on
emp.DesignationId equals designation.Id
where emp.Code == userCode
select new EmployeeDetails
{
firstname = emp.FirstName,
lastname = emp.LastName,
designation = designation.Title,
LocationId = wsdetails.location,
WorkStationName = wsdetails.workstation
}).SingleOrDefault();
As a workaround I can check
if wsdetails == null
and change my second LINQ logic, but I believe there are some ways to handle null values in LINQ itself like the ?? operator.
But I tried this and it didn't work for me.
Any help?
The problem is EF can't translate the null-coalescing operator to SQL. Personally I don't see what's wrong with checking the result with an if statement before executing the next query. However, if you don't want to do that, then because your result is always going to be a single query why not do something like:
var wsdetails = (from assetTable in Repository.Asset
join userAsset in Repository.UserAsset on
assetTable.Asset_Id equals userAsset.Asset_Id
join subLocationTable in Repository.SubLocation on
assetTable.Sub_Location_Id equals subLocationTable.Sub_Location_ID
where userAsset.User_Id == userCode
&& assetTable.Asset_TypeId == 1 && assetTable.Asset_SubType_Id == 1
select new { workstation = subLocationTable.Sub_Location_Name, location = assetTable.Location_Id }).FirstOrDefault();
result = (from emp in this.Repository.Employee
join designation in this.Repository.Designation on
emp.DesignationId equals designation.Id
where emp.Code == userCode
select new EmployeeDetails
{
firstname = emp.FirstName,
lastname = emp.LastName,
designation = designation.Title
}).SingleOrDefault();
result.LocationId = wsdetails != null ? wsdetails.location : "someDefaultValue";
result.WorkStationName = wsdetails != null ? wsdetails.workstation ?? "someDefaultValue";
Instead of the "binary" operator ?? maybe you should use the good old ternary one, ? :, like in
wsdetails != null ? wsdetails.location : null
Try not evaluating the first query, and use it in the second query. This should result in a single SQL statement.
var wsdetails = (from assetTable in Repository.Asset
join userAsset in Repository.UserAsset on
assetTable.Asset_Id equals userAsset.Asset_Id
join subLocationTable in Repository.SubLocation on
assetTable.Sub_Location_Id equals subLocationTable.Sub_Location_ID
where userAsset.User_Id == userCode
&& assetTable.Asset_TypeId == 1 && assetTable.Asset_SubType_Id == 1
select new { workstation = subLocationTable.Sub_Location_Name, location = assetTable.Location_Id });
// wsdetails is still an IEnumerable/IQueryable
result = (from emp in this.Repository.Employee
join designation in this.Repository.Designation on
emp.DesignationId equals designation.Id
where emp.Code == userCode
select new EmployeeDetails
{
firstname = emp.FirstName,
lastname = emp.LastName,
designation = designation.Title,
LocationId = wsdetails.First().location,
WorkStationName = wsdetails.First().workstation
}).SingleOrDefault();

Categories