Linq to entities hard code list - c#

This is my view model
public class ProcurementDisplayData
{
public string Key { get; set;}
public string Value { get; set;}
}
How can I hard code this list. Basically what will be the syntax inside the query
var query = (from u in context.Jobs
join q in context.Quotations on u.QuotationId equals q.QuotationId
join v in context.Vessels on q.VesselId equals v.VesselId
join c in context.Customers on q.CustomerId equals c.CustomerId
where u.JobNo == JobNo
select new List<ProcurementDisplayData>
{
new { Key = "a" ,Value=u.JobNo},
new { Key = "b" ,Value=u.Vessel}
}).ToList();
return query;

Get JobNo and Vessel from database. Then create lists in memory:
var query = from u in context.Jobs
join q in context.Quotations on u.QuotationId equals q.QuotationId
join c in context.Customers on q.CustomerId equals c.CustomerId
where u.JobNo == JobNo
select new { u.JobNo, u.Vessel };
return query.AsEnumerable() // moves further processing to memory
.Select(x => new List<ProcurementDisplayData> {
new { Key = "a", Value = x.JobNo },
new { Key = "b", Value = x.Vessel }
}).ToList();

Related

Select new object that contains a list of other objects in Linq

I have an object that contains lists of other objects.
public class MyNewClassWithEverything
{
public MasterItem itemMaster { get; set; }
public Item item { get; set; }
public List<Itemfields> Itemsfields { get; set; }
public List<ItemMasterfields> ItemMasterfields { get; set; }
}
In my Linq i have
var mainData = from uo in _context.UserOrgs
join m in _context.MasterItem on uo.Organization equals m.Organization
join i in _context.Item on m.Id equals i.MasterId
join p in _context.ItemMasterfields on i.MasterId equals p.MasterId
join z in _context.Itemfields on i.Id equals z.ItemId
where uo.UserId == 6923 && m.DatePaid >= PaymentStartDate && m.DatePaid < PaymentEndDate
select new MyNewClassWithEverything
{
Itemsfields = new List<Itemsfields> { z },
ItemMasterfields = new List<ItemMasterfields> { p },
ItemMaster = m,
Items = i
};
However when i run my app i am getting an exception
The given expression 'new MyNewClassWithEverything()
does not contain the searched expression '[z]' in a nested
NewExpression with member assignments or a MemberBindingExpression
How should i be populating the new list?
You can try to use _context.Itemfields.Where get the collection in property instead of linq join.
var mainData = from uo in _context.UserOrgs
join m in _context.MasterItem on uo.Organization equals m.Organization
join i in _context.Item on m.Id equals i.MasterId
where uo.UserId == 6923 && m.DatePaid >= PaymentStartDate && m.DatePaid < PaymentEndDate
select new MyNewClassWithEverything
{
Itemsfields = _context.Itemfields.Where(x=>x.ItemId == i.Id).toList(),
ItemMasterfields = _context.ItemMasterfields.Where(l=>l.MasterId == i.MasterId).toList(),
ItemMaster = m,
Items = i
};
You can add an into clause in your join to use the joined records as a group:
var mainData = from uo in _context.UserOrgs
join m in _context.MasterItem on uo.Organization equals m.Organization
join i in _context.Item on m.Id equals i.MasterId
join p in _context.ItemMasterfields on i.MasterId equals p.MasterId
into ps
join z in _context.Itemfields on i.Id equals z.ItemId
into zs
where uo.UserId == 6923 && m.DatePaid >= PaymentStartDate && m.DatePaid < PaymentEndDate
select new MyNewClassWithEverything
{
Itemsfields = zs.ToList(),
ItemMasterfields = ps.ToList(),
ItemMaster = m,
Items = i
};
If you get an error on ToList, you can either change your property types to IEnumerable<T> or call AsEnuerable() and do a second projection to turn the groups into list outside of the EF query.

Join two linq queries on one key column to get one result set

Here I want to join the out put of the first query(one column) to the result of the 2nd query to get a one result set. How can I merge them.(CONCAT doesn't work as required. eg: var query2 = query.concat(query1);)
var query = (from PP in _db.paymentPlans
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new {C,PP} by new {C.courseID} into totalRecievable
select new PdPpAppCourseModel
{
courseID = totalRecievable.Key.courseID,
totalAmount = totalRecievable.Sum(x => x.PP.totalAmount)
}).ToList();
var query1=(from PD in _db.paymentDetails
join PP in _db.paymentPlans on PD.paymentPlanID equals PP.paymentPlanID
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new { C,PD } by new { C.courseID, C.cricosCode, C.courseName } into paymentsCourseWise
select new PdPpAppCourseModel
{
courseID = paymentsCourseWise.Key.courseID,
cricosCode = paymentsCourseWise.Key.cricosCode,
courseName = paymentsCourseWise.Key.courseName,
paidAmount = paymentsCourseWise.Sum(x => x.PD.paidAmount)
}).ToList();
You could join query1 and query like this
var result = (from q1 in query1
join q in query on q1.courseID = q.courseID
select new PdPpAppCourseModel
{
courseID = q1.Key.courseID,
cricosCode = q1.Key.cricosCode,
courseName = q1.Key.courseName,
paidAmount = q1.Sum(x => x.PD.paidAmount),
totalAmount = q.totalAmount
}).ToList();

how to combine and sum up the result from two lists based on unique id

i have a method which retrives two lists.
and i am showing the list based on union .
but i want to sum the amount based on the unique id which is FC_Id
public List<ContractFundingCategory> CalculateContractFundingCategoryAmountbyPurchaseOrder(int poId, string serviceType)
{
List<ContractFundingCategory> lstContractFundingCategory = new List<ContractFundingCategory>();
var lstContractFundingCategoryEbs =
(
from payment in context.PaymentDetails
join reimEbs in context.Reimbursement_EBSUtilization on payment.REU_Id equals reimEbs.Id into ebs_join
from reimEbs in ebs_join.DefaultIfEmpty()
join purc in context.PurchaseOrders on payment.PO_Id equals purc.Id
join serviceDetail in context.fServiceDetails on reimEbs.SD_Id equals serviceDetail.Id
join fundingCategory in context.fFundingCategories on serviceDetail.FC_Id equals fundingCategory.Id into fundingCategory_Join
from fundingCategory in fundingCategory_Join.DefaultIfEmpty()
where payment.PO_Id == poId && (serviceDetail.ServiceType == serviceType)
group new { fundingCategory, payment, serviceDetail } by new
{
fundingCategory.Id,
serviceDetail.ServiceType,
} into grp
select new
{
FC_Id = grp.Key.Id,
serviceType = grp.Key.ServiceType,
BudgetAmount = grp.Sum(p => p.payment.PaymentAmount),
}
)
.AsEnumerable().Select(x => new ContractFundingCategory
{
FC_Id = x.FC_Id,
BudgetAmount = x.BudgetAmount,
ServiceType = x.serviceType.ToString()
}).ToList();
var lstContractFundingCategoryCds =
(
from payment in context.PaymentDetails
join reimCds in context.Reimbursement_CDSUtilization on payment.RCU_Id equals reimCds.Id into cds_join
from reimCds in cds_join.DefaultIfEmpty()
join cdsutil in context.CDSUtilizations on reimCds.CDSU_Id equals cdsutil.Id
join purc in context.PurchaseOrders on payment.PO_Id equals purc.Id
join serviceDetail in context.fServiceDetails on cdsutil.ServiceDetail_Id equals serviceDetail.Id
join fundingCategory in context.fFundingCategories on serviceDetail.FC_Id equals fundingCategory.Id into fundingCategory_Join
from fundingCategory in fundingCategory_Join.DefaultIfEmpty()
where payment.PO_Id == poId && (serviceDetail.ServiceType == serviceType)
group new { fundingCategory, payment, serviceDetail } by new
{
fundingCategory.Id,
serviceDetail.ServiceType,
} into grp
select new
{
FC_Id = grp.Key.Id,
serviceType = grp.Key.ServiceType,
BudgetAmount = grp.Sum(p => p.payment.PaymentAmount),
}
)
.AsEnumerable().Select(x => new ContractFundingCategory
{
FC_Id = x.FC_Id,
BudgetAmount = x.BudgetAmount,
ServiceType = x.serviceType.ToString()
}).ToList();
//lstContractFundingCategory.AddRange(lstContractFundingCategoryEbs);
//lstContractFundingCategory.AddRange(lstContractFundingCategoryCds);
//List<ContractFundingCategory> a = new List<ContractFundingCategory>();
lstContractFundingCategory = lstContractFundingCategoryEbs
.Union(lstContractFundingCategoryCds)
.ToList();
return lstContractFundingCategory;
}
Can any one help me with out writing a loop statement
lstContractFundingCategory.Aggregate(new Dictionary<int,int>(), (acc,elem) => { acc.ContainsKey(elem.FC_Id) ? acc[elem.FC_Id] += elem.BudgetAmount : acc.Add(elem.FC_Id, elem.BudgetAmount); return acc; });
Aggregate is a fold analogue which iterates your value and applies them to an accumulator. In this case, we're providing a new dictionary as the accumulator. The anonymous function is checking to see if the dictionary has your key; if it does, then it adds the budget value to the current value, and if it doesn't adding the key with the initial budget value. It will return a Dictionary with the keys being your unique FC_Id's and their values being the sum total of those budgets.

Populating a List in a Strongly Typed LINQ to Entities Query

I am relatively new to LINQ and I'm simply trying to populate a List in a LINQ to Entities query. Any assistance would be greatly appreciated.
The class "SearchCriteria" looks like this:
public class SearchCriteria
{
public IList<DTOEventType1> eventTypes { get; set; }
public IList<DTOLocation1> locs { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true,
DataFormatString="0:dd/MM/yyyy}")]
public DateTime? searchDate { get; set; }
public List<PortfolioLibraryMVC4V2.Domain.DTO.DTOCalendarEvents>
CalendarEvents;
}
and my query is shown below:
var query = from E in medRepo.evt
join L in medRepo.loc on E.LocationID equals L.LocationID
join ET in medRepo.evtType on E.EventTypeID equals
ET.EventTypeID
where IDsOfSelectedEventTypes.Contains(E.EventTypeID) &&
IDsOfSelectedLocations.Contains(L.LocationID) &&
E.EventStart > eventslocs.searchDate
select new SearchCriteria
{
CalendarEvents = query.Select(x => new DTOCalendarEvents
{
Name = ET.Name,
EventStart = E.EventStart,
EventEnd = E.EventEnd
}).ToList()
};
var datalist = query.ToList();
I'm trying to populate the list "CalendarEvents" in the Class SearchCriteria in the select in the above query. Currently, I get the error message "trying to use the local variable query before it is declared" so obviously my syntax isn't correct. Can someone show me the proper way to do this?
Thanks,
Pete
Give this is a try:
var query = from E in medRepo.evt
join L in medRepo.loc on E.LocationID equals L.LocationID
join ET in medRepo.evtType on E.EventTypeID equals
ET.EventTypeID
where IDsOfSelectedEventTypes.Contains(E.EventTypeID) &&
IDsOfSelectedLocations.Contains(L.LocationID) &&
E.EventStart > eventslocs.searchDate
select new DTOCalendarEvents
{
Name = ET.Name,
EventStart = E.EventStart,
EventEnd = E.EventEnd
};
var datalist = query.ToList();
var searchCriteria = new SearchCriteria();
searchCriteria.CalendarOfEvents = datalist;
You can take SearchCriteria outside of the linq query..
var searchCriteria = new SearchCriteria();
searchCriteria.CalendarEvents = (from E in medRepo.evt
join L in medRepo.loc
on E.LocationID equals L.LocationID
join ET in medRepo.evtType
on E.EventTypeID equals ET.EventTypeID
where
IDsOfSelectedEventTypes.Contains(E.EventTypeID)
&& IDsOfSelectedLocations.Contains(L.LocationID)
&& E.EventStart > eventslocs.searchDate)
.Select(x => new DTOCalendarEvents
{
Name = ET.Name,
EventStart = E.EventStart,
EventEnd = E.EventEnd
})
.ToList();
basically we only need the list of events from the LINQ query.

linq combine 2 tables into one list

I have 2 tables in db - one is EmploymentRecords one is EmploymentVerificationRecords
I want to query both tables and return one List
I have a Model (simplified example):
Public Class Record
{
int ID {get; set;}
string name {get; set;}
bool IsVerification {get; set;}
}
I want to have some type of query in LINQ like :
var records = from a in _context.EmploymentRecords
join b in _context.EmploymentVerificationRecords on a.id equals b.id
where a.UserID = 1
select new Record() { .ID = a.id, .name = a.name, .IsVerification = false}
// I also want to select a new Record() for each b found
see - I also want a new Record() added to the results for each record found in the second table , for these results IsVerification would be True
You can select everything from DB as it is selected now (but I would rather use join/into to do that) and then flatten results into one big collection using LINQ to Objects.
Following should do the trick:
var records
= (from a in _context.EmploymentRecords
join b in _context.EmploymentVerificationRecords on a.id equals b.id into bc
where a.UserID = 1
select new {
a = new Record() { ID = a.id, name = a.name, IsVerification = false},
b = bc.Select(x => new Record() { ID = x.ID, name = b.name, IsVerification = true })
}).AsEnumerable()
.SelectMany(x => (new [] { x.a }).Concat(x.b));

Categories