Is it a lazy loading query or Eager Loading ? , Slow Query, Performance needed please - asp.net-mvc-2

First, I would like to know if this query is Lazy loading or Eager loading. I Read a lot on both, and not sure if I understand the difference between each other.
2- I Get this query, This query take a lot of time to execute. Anybody have some suggest when you see this query. I'll do all modification needed to speed up this query.
Note: I just want your opinion about this query and method.
Thanks a lot.
public SearchLocationViewModel GetSearchLocationViewModel( string CivicNumber = null ,
string Street = null,
string City = null,
List<int?> ListCountryID = null,
List<int?> ListStateID = null,
int IsActive =1,
string SortField ="FileNumber",
string SortDirection = "asc" ,
List<int?> GrpDescID1 = null,
List<int?> GrpDescID2 = null,
List<int?> GrpDescID3 = null,
List<int?> GrpDescID4 = null,
int LocationTypeID = -1,
List<int?> ListUsageID = null)
{
if (GrpDescID1 == null)
{
GrpDescID1 = new List<int?>();
}
if (GrpDescID2 == null)
{
GrpDescID2 = new List<int?>();
}
if (GrpDescID3 == null)
{
GrpDescID3 = new List<int?>();
}
if (GrpDescID4 == null)
{
GrpDescID4 = new List<int?>();
}
if (ListCountryID == null)
{
ListCountryID = new List<int?>();
}
if (ListStateID == null)
{
ListStateID = new List<int?>();
}
if (ListUsageID == null)
{
ListUsageID = new List<int?>();
}
GrpDescID1.Remove(GrpDescID1.SingleOrDefault(p => p < 0));
GrpDescID2.Remove(GrpDescID2.SingleOrDefault(p => p < 0));
GrpDescID3.Remove(GrpDescID3.SingleOrDefault(p => p < 0));
GrpDescID4.Remove(GrpDescID4.SingleOrDefault(p => p < 0));
ListCountryID.Remove(ListCountryID.SingleOrDefault(p => p < 0));
ListStateID.Remove(ListStateID.SingleOrDefault(p => p < 0));
ListUsageID.Remove(ListUsageID.SingleOrDefault(p => p < 0));
int lang = BaseStaticClass.CurrentLangID();
int UserID = Convert.ToInt32(Session["UserID"]);
SearchLocationViewModel ViewModel = InitSearchViewModel();
IGrpRepository repGrp = new GrpRepository(_db);
ICountryRepository repCountry = new CountryRepository(_db);
IProvinceRepository repProvince = new ProvinceRepository(_db);
ViewModel.Perm = repPermission;
ViewModel. CivicNumber = CivicNumber ;
ViewModel. Street = Street;
ViewModel. City = City;
ViewModel. IsActive =IsActive;
ViewModel. SortField =SortField;
ViewModel. SortDirection = SortDirection ;
ViewModel.ListCountry = repCountry.GetCountryForSearchByUser(true,UserID);
ViewModel.ListProvince = repProvince.GetProvinceSearchByUserID(true, UserID);
ViewModel.ListGrpDescID1 =GrpDescID1;
ViewModel.ListGrpDescID2 = GrpDescID2;
ViewModel.ListGrpDescID3 = GrpDescID3;
ViewModel.ListGrpDescID4 = GrpDescID4;
ViewModel.ListCountryID = ListCountryID;
ViewModel.ListStateID = ListStateID;
ViewModel.LocationTypeID = LocationTypeID;
ViewModel.ListUsageID = ListUsageID;
var LocationType = new SelectList(repGeneric.GetTextByCurrentLang<LocationType, LocationTypeText>(), "ID", "Txt").ToList();
bc.AddDropdownSearchValueNoNew(ref LocationType);
var ListUsage = new SelectList(repGeneric.GetTextByCurrentLang<Usage, UsageText>(), "ID", "Txt").ToList();
ViewModel.ListUsage = ListUsage;
ViewModel.ListLocationType = LocationType;
var ListGrp1 = new SelectList(repGrp.GetAllGrpDescTextForUserByLevel(UserID, 1).AsEnumerable(), "GrpDescID", "GrpDescTxt").ToList();
var ListGrp2 = new SelectList(repGrp.GetAllGrpDescTextForUserByLevel(UserID, 2).AsEnumerable(), "GrpDescID", "GrpDescTxt").ToList();
var ListGrp3 = new SelectList(repGrp.GetAllGrpDescTextForUserByLevel(UserID, 3).AsEnumerable(), "GrpDescID", "GrpDescTxt").ToList();
var ListGrp4 = new SelectList(repGrp.GetAllGrpDescTextForUserByLevel(UserID, 4).AsEnumerable(), "GrpDescID", "GrpDescTxt").ToList();
var t1 = ListGrp1.Select(s => (int?)Convert.ToInt32(s.Value));
var t2 = ListGrp2.Select(s => (int?)Convert.ToInt32(s.Value));
var t3 = ListGrp3.Select(s => (int?)Convert.ToInt32(s.Value));
var t4 = ListGrp4.Select(s => (int?)Convert.ToInt32(s.Value));
ViewModel.ListGrp1 = ListGrp1;
ViewModel.ListGrp2 = ListGrp2;
ViewModel.ListGrp3 = ListGrp3;
ViewModel.ListGrp4 = ListGrp4;
ViewModel.ListGrpTogether = new List<SelectListItem>();
if(ViewModel.GrpName1 != "")
ViewModel.ListGrpTogether.Add(new SelectListItem() { Text = ViewModel.GrpName1 ,Value = "1"});
if (ViewModel.GrpName2 != "")
ViewModel.ListGrpTogether.Add(new SelectListItem() { Text = ViewModel.GrpName2, Value = "2" });
if (ViewModel.GrpName3 != "")
ViewModel.ListGrpTogether.Add(new SelectListItem() { Text = ViewModel.GrpName3, Value = "3" });
if (ViewModel.GrpName4 != "")
ViewModel.ListGrpTogether.Add(new SelectListItem() { Text = ViewModel.GrpName4, Value = "4" });
ViewModel.ListGrpTogether.Insert(0, new SelectListItem() { Text = ViewRes.GeneralString.Choose, Value = "-1", Selected = true });
int iUserID = Convert.ToInt32(Session["UserID"]);
//this is use for Permission
//Get all the user permission about group and province
IEnumerable<int?> usrGrpDesc = _db.UserGroupDescs.Where(p => p.UserID == iUserID).Select(s => s.GrpDescID);
IEnumerable<int?> usrProvince = _db.UserProvinces.Where(p => p.UserID == iUserID).Select(s => s.PrvID);
var ListLocation = from s in _db.Locations.Where(p =>
p.IsDelete == false &&
(IsActive < 0 || IsActive == (p.IsActive == true ? 1 : 0)) &&
(LocationTypeID < 0 || LocationTypeID == p.LocationTypeID) &&
(City == null || p.Address.City.CityName.Contains(City)) &&
(ListUsageID.Count() == 0 || p.Premises.Select(gs => gs.UsageID).Intersect(ListUsageID).Any()) &&
(ListCountryID.Count() == 0 || ListCountryID.Any(pl => pl == p.Address.City.Province.Country.CtryID)) &&
(ListStateID.Count() == 0 || ListStateID.Any(pl => pl == p.Address.City.Province.PrvID)) &&
(Street == null || p.Address.Street.Contains(Street)) &&
(CivicNumber == null || p.Address.CivicNumber.Contains(CivicNumber)) &&
((GrpDescID1.Count() == 0 )|| p.GroupLocations.Select(gs => gs.GrpDescID).Intersect(GrpDescID1).Any()) &&
((GrpDescID2.Count() == 0)|| p.GroupLocations.Select(gs => gs.GrpDescID).Intersect(GrpDescID2).Any()) &&
((GrpDescID3.Count() == 0) || p.GroupLocations.Select(gs => gs.GrpDescID).Intersect(GrpDescID3).Any()) &&
((GrpDescID4.Count() == 0 ) || p.GroupLocations.Select(gs => gs.GrpDescID).Intersect(GrpDescID4).Any()) &&
(p.GroupLocations.Select(gs => gs.GrpDescID).Intersect(usrGrpDesc).Any()) &&
((p.Address.City == null || usrProvince.Any(ps => ps.Value == p.Address.City.PrvID)))
)
select new LocationViewModel()
{
LocationID = s.LocationID,
LocationTypeID = s.LocationTypeID,
Long = s.Address.Longitude,
Lat = s.Address.Latitude,
FileNumber = s.LocationFile,
State = s.Address.City.Province.PrvName,
City = s.Address.City.CityName,
Address = s.Address.CivicNumber + " " + s.Address.Street,
Status = s.LocationType.LocationTypeTexts.Where(h => h.Txt != "" && h.LangID == lang || h.LangID == 1).OrderByDescending(g => g.LangID).FirstOrDefault().Txt,
ListGroupe1 = s.GroupLocations.Where(g=>g.GrpDesc.Grp.GrpLevel == 1).Select(grpLoc => grpLoc.GrpDesc.GrpDescTexts.Where(h => h.GrpDescTxt != "" && (h.LangID == lang || h.LangID == 1)).OrderByDescending(g => g.LangID).FirstOrDefault()).Select(txt => txt.GrpDescTxt),
ListGroupe2 = s.GroupLocations.Where(g => g.GrpDesc.Grp.GrpLevel == 2).Select(grpLoc => grpLoc.GrpDesc.GrpDescTexts.Where(h => h.GrpDescTxt != "" && (h.LangID == lang || h.LangID == 1)).OrderByDescending(g => g.LangID).FirstOrDefault()).Select(txt => txt.GrpDescTxt),
ListGroupe3 = s.GroupLocations.Where(g=>g.GrpDesc.Grp.GrpLevel == 3).Select(grpLoc => grpLoc.GrpDesc.GrpDescTexts.Where(h => h.GrpDescTxt != "" && (h.LangID == lang || h.LangID == 1)).OrderByDescending(g => g.LangID).FirstOrDefault()).Select(txt => txt.GrpDescTxt),
ListGroupe4 = s.GroupLocations.Where(g=>g.GrpDesc.Grp.GrpLevel == 4).Select(grpLoc => grpLoc.GrpDesc.GrpDescTexts.Where(h => h.GrpDescTxt != "" && (h.LangID == lang || h.LangID == 1)).OrderByDescending(g => g.LangID).FirstOrDefault()).Select(txt => txt.GrpDescTxt),
DefaultImgPath = s.LocationPictures.Where(p=>p.IsDefault == true && p.IsActive == true).FirstOrDefault().FilePath,
HasPremises = s.Premises.Any(p => p.IsActive == true && p.IsDelete == false)
};
ViewModel.ListLocation = ListLocation.ToList();
return ViewModel;
}

Lazy loading is deferring initialization of an object until the point at which it is needed. If you returned your ListLocation back to its caller, as you've written above, with no .ToList() (or other), then you'd be consuming this lazily.
Eager loading is having the results of your query gathered at the time that the query is defined. In this case it'd be retrieving the results of your LINQ query all at once (at the time that the query is constrcuted). Usually a .ToList() or .Single() or other will do this for you.
I suspect you're consuming the results your LINQ query (var ListLocation) later in your code. Your code above is using a lazy-loaded approach.
You're showing that you're calling .ToList(), so you're indeed using eager-loading; even though it's on a different statement/line of code.
Performance: I'm not 100% on this being your perf problem, but I'd refactor your LINQ into something like this, using an extension method .WhereIf(). It's a heck of a lot easier to read and write.
var ListLocation = from s in _db.Locations
.Where(p => p.IsDelete == false)
.WhereIf(IsActive >= 0, p=> IsActive == (p.IsActive == true ? 1 : 0))
.WhereIf(LocationTypeID >= 0, p=> LocationTypeID == p.LocationTypeID
.WhereIf(City!=null, p=> p.Address.City.CityName.Contains(City)) //etc

If you're using this, and it works, then you're probably lazy loading, since you don't have any calls to .Include().

Related

Upgraded to .NET Core 3.1 and receiving an error in a LINQ query related to using .FirstOrDefault()

I have an Entity Framework controller that has been using the method below successfully. However I recently updated my project to use .NET Core 3.1 and it must've broken something.
I am now getting this error:
FirstOrDefault()' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()
I did some research, and some people say not to use GroupBy extension which I do in the query below. I tried to take it out, but that just generates more errors.
I also went to this:
But I couldn't figure out how to fix my complex query below.
Honestly, I'm not sure why it's failing or how to properly fix it.
Does anyone see anything wrong?
Thanks!
public async Task<ActionResult<object>> GetStarChemicalData(string starID)
{
var starChemicalData = await (from starlist in _context.StarList
join ql in _context.ChemicalList on starlist.ChemicalId equals ql.ChemicalId into stars
from chemicallist in stars.DefaultIfEmpty()
join qc in _context.ChemicalAtoms on chemicallist.ChemicalId equals qc.ChemicalId into chemicals
from chemicalatoms in chemicals.DefaultIfEmpty()
join nk in _context.StarLinks on chemicalatoms.AtomId equals nk.AtomId into links
from starlinks in links.DefaultIfEmpty()
where starlist.StarId == starID
select new
{
StarId = starlist.StarId,
StarType = starlist.StarType,
StarTitle = starlist.StarTitle,
ChemicalId = starlist.ChemicalId,
AtomId = (Guid?)chemicalatoms.AtomId,
OrderId = chemicalatoms.OrderId,
ChemicalText = chemicallist.ChemicalText,
AtomText = chemicalatoms.AtomText,
Wavelength = chemicalatoms.Wavelength,
isRedShifted = (starlinks.AtomId != null && starlist.StarType == 1) ? 1
: (starlinks.AtomId == null && starlist.StarType == 1) ? 0
: (int?)null
})
.GroupBy(x => x.StarId)
.Select(g => new
{
StarId = g.FirstOrDefault().StarId,
StarType = g.FirstOrDefault().StarType,
StarTitle = g.FirstOrDefault().StarTitle,
ChemicalId = g.FirstOrDefault().ChemicalId,
ChemicalText = g.FirstOrDefault().ChemicalText,
ChemicalAtoms = (g.FirstOrDefault().AtomId != null ? g.Select(x => new
{
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
}) : null)
}).FirstOrDefaultAsync();
return starChemicalData;
ERROR AFTER DEBUGGING:
.Select(x => new {
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
})' could not be translated.
You have alot of FirstOrDefault (s) calls.
To code them "safely", you can try this:
.FirstOrDefault() ?? string.Empty
or
.FirstOrDefault() ?? 0
..
the above is a short hand version of this: (null check + ? ternary operator) (again, this is a "safe" way to code it)
StarId = null == g.FirstOrDefault() ? 0 : g.FirstOrDefault().StarId,
StarType = null == g.FirstOrDefault() ? string.Empty : g.FirstOrDefault().StarType,
StarTitle = null == g.FirstOrDefault() ? string.Empty : g.FirstOrDefault().StarTitle,
..
But better to debug, to figure out what is wrong
Change ALL OF these (temporarilty) to "" and 0
I'm listing 3 of them, but you should change all of them
instead of this:
StarId = g.FirstOrDefault().StarId,
StarType = g.FirstOrDefault().StarType,
StarTitle = g.FirstOrDefault().StarTitle,
use (temporarily) this:
StarId = 0,
StarType = "",
StarTitle = "",
(again do ALL of them)
and one-by-one, replace them back
StarId = g.FirstOrDefault().StarId,
StarType = "",
StarTitle = "",
to find the "culprit".
Here is some pseudo code.......that you can try to use the intermediate step of IQueryable. Its pseduo code, you'll have to tweak.
IQueryable is a way to "slowly build up the query" instead of writing a single super query.......and helps with debugging. Eventually, you will comment out (or delete) ... tempDebuggingCollection ........ but it can help get you to where you want to go.
public async Task<ActionResult<object>> GetStarChemicalData(string starID)
{
IQueryable<YourObjectHere> starChemicalDataQueryable = await (from starlist in _context.StarList
join ql in _context.ChemicalList on starlist.ChemicalId equals ql.ChemicalId into stars
from chemicallist in stars.DefaultIfEmpty()
join qc in _context.ChemicalAtoms on chemicallist.ChemicalId equals qc.ChemicalId into chemicals
from chemicalatoms in chemicals.DefaultIfEmpty()
join nk in _context.StarLinks on chemicalatoms.AtomId equals nk.AtomId into links
from starlinks in links.DefaultIfEmpty()
where starlist.StarId == starID;
ICollection<YourObjectHere> tempDebuggingCollection = starChemicalDataQueryable.ToListAsync(CancellationToken.None);
var starChemicalData = starChemicalDataQueryable
select new
{
StarId = starlist.StarId,
StarType = starlist.StarType,
StarTitle = starlist.StarTitle,
ChemicalId = starlist.ChemicalId,
AtomId = (Guid?)chemicalatoms.AtomId,
OrderId = chemicalatoms.OrderId,
ChemicalText = chemicallist.ChemicalText,
AtomText = chemicalatoms.AtomText,
Wavelength = chemicalatoms.Wavelength,
isRedShifted = (starlinks.AtomId != null && starlist.StarType == 1) ? 1
: (starlinks.AtomId == null && starlist.StarType == 1) ? 0
: (int?)null
})
.GroupBy(x => x.StarId)
.Select(g => new
{
StarId = g.FirstOrDefault().StarId,
StarType = g.FirstOrDefault().StarType,
StarTitle = g.FirstOrDefault().StarTitle,
ChemicalId = g.FirstOrDefault().ChemicalId,
ChemicalText = g.FirstOrDefault().ChemicalText,
ChemicalAtoms = (g.FirstOrDefault().AtomId != null ? g.Select(x => new
{
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
}) : null)
}).FirstOrDefaultAsync();
return starChemicalData;
............
AGain, same safe checks:
ChemicalAtoms = (g.FirstOrDefault().AtomId != null ? g.Select(x => new
{
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
}) : null)
You are not safely checking for g.FirstOrDefault() ....
something like this:
ChemicalAtoms = null == g.FirstOrDefault() ? null : (g.FirstOrDefault().AtomId != null ? g.Select(x => new
{
AtomId = x.AtomId,
OrderId = x.OrderId,
AtomText = x.AtomText,
Feedback = x.Wavelength,
IsCorrect = x.isRedShifted
}) : null)

Unable to create a constant value of type <object>. Only primitive types or enumeration types are supported in this context

I am using the following code:
public static Grid.GridResult GetExamDetailsForGrid(Grid.GridFilter Filter, int userid, int _user_roleid, int selectedYear,string Tin,string Measure, DateTime? Startdate, DateTime? Enddate)
{
Grid.GridResult _examsEntered = new Grid.GridResult();
using (var entity = new PQRSEntityContainer())
{
((IObjectContextAdapter)entity).ObjectContext.CommandTimeout = 120;
var Measureid = 0;
if(!string.IsNullOrEmpty(Measure))
{
Measureid = entity.tbl_Lookup_Measure.Where(m => m.CMSYear == selectedYear && m.Measure_num == Measure)
.Select(v => v.Measure_ID).FirstOrDefault();
}
var _username = CurrentUser.UserName;
var npi = FileProcessBL.getNPINumber(userid);
var cmsYear = selectedYear != 0 ? selectedYear : 0;
var Newtin= string.IsNullOrEmpty(Tin) ? null : Tin;
var NewStartdate = Startdate ==null ? null : Startdate;
var NewEnddate = Enddate == null ? null : Enddate;
var NewMes= string.IsNullOrEmpty(Measure) ? null : Measure;
var liDetails = (from ex in entity.tbl_Exam.Where(i => i.Physician_NPI == npi && i.CMS_Submission_Year == cmsYear
&& i.Exam_TIN == (Newtin==null?i.Exam_TIN:Newtin)
&& i.Exam_Date >= (NewStartdate == null ? i.Exam_Date : NewStartdate)
&& i.Exam_Date <= (NewEnddate == null ? i.Exam_Date : NewEnddate))
from exmes in entity.tbl_Exam_Measure_Data.Where(i => i.Exam_Id == ex.Exam_Id
&& i.Measure_ID== (Measureid == 0 ? i.Measure_ID : Measureid) ).DefaultIfEmpty()
from nume in entity.tbl_lookup_Numerator_Code.Where(nume => exmes.tbl_Lookup_Measure.Measure_ID == nume.tbl_Lookup_Measure.Measure_ID && exmes.Numerator_response_value == nume.Numerator_response_Value).DefaultIfEmpty()
join sc in entity.tbl_Lookup_Data_Source on ex.DataSource_Id equals sc.DataSource_Id
where exmes.Exam_Id != null
select new MesCasesGrid
{
NPI = ex.Physician_NPI,
TIN = ex.Exam_TIN == null ? "" : ex.Exam_TIN,
ExamID = ex.Exam_Id,
//MeasureID = exMes.Measure_ID,
MeasureID = (exmes != null) ? exmes.Measure_ID : 0,
MeasureNum = (exmes != null) ? exmes.tbl_Lookup_Measure.Measure_num : null,
CPTCode = (exmes != null) ? exmes.Denominator_proc_code : null,
///NumeratorCode = (exmes!=null)?exmes.tbl_Lookup_Measure.tbl_lookup_Numerator_Code.Select(i=>i.Numerator_Code).FirstOrDefault():null,
NumeratorCode = nume.Numerator_Code,
Created_Date = ex.Created_Date,
ExamDate = ex.Exam_Date,
UniqueExamID = ex.Exam_Unique_ID,
PatientGender = (ex.Patient_Gender == "M" ? "Male" : ex.Patient_Gender == "F" ? "Female" : ex.Patient_Gender == "O" ? "Other" : ex.Patient_Gender == "U" ? "Unknown" : ""),
PatientID = ex.Patient_ID,
isEncrypt = ex.IsEncrypt,
PatientAge = ex.Patient_Age,
StatusDesc = (exmes != null) ? exmes.tbl_Lookup_Measure_Status.Status_Desc : null,
///Type =ex.DataSource,
Type = sc.DataSource,
cmsYear = ex.CMS_Submission_Year
}).Distinct().ToList();
if (_user_roleid == Constants.FacilityAdminID || _user_roleid == Constants.FacilityUserID || _user_roleid == Constants.RegistryAdminID
|| _user_roleid == Constants.SuperCorporateAdminID || _user_roleid == Constants.CorporateAdminID || _user_roleid == Constants.ServiceUserID) // jira-579
{
var facilityTins = entity.sp_getFacilityTIN(_username).Select(x => x.TIN).ToList();
liDetails = liDetails.Where(i => facilityTins.Contains(i.TIN)).Select(x => x).Distinct().ToList();
}
var value = Convert.ToBoolean(1);
foreach (var item in liDetails)
{
if (item.isEncrypt == value && item.PatientID != null)
{
try
{
var patidDecrypt = AesHelper.Decrypt256(item.PatientID);
item.PatientID = patidDecrypt;
}
catch (Exception ex)
{
}
}
}
return _examsEntered;
}
}
I have recently added the following code above method:
i.Measure_ID == && i.Measure_ID== (Measureid == 0 ? i.Measure_ID : Measureid)
When adding the highlighted code to this method I am getting following error:
:Error in RecordEnteredGridBind()
System.NotSupportedException: Unable to create a constant value of type 'DAL.Entities.tbl_Exam_Measure_Data'. Only primitive types or enumeration types are supported in this context.
at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.NewArrayInitTranslator.<>c__DisplayClass1_0.<TypedTranslate>b__0(Expression e)
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator3.Validate(IEnumerable1 argument, String argumentName, Int32 expectedElementCount, Boolean allowEmpty, Func3 map, Func2 collect, Func3 deriveName)
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator3.Validate()
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.CreateExpressionList(IEnumerable1 arguments, String argumentName, Boolean allowEmpty, Action2 validationCallback)
at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateNewCollection(IEnumerable`1 elements, DbExpressionList& validElements)
I have tried lot of ways but not working. So, Can anyone help me?

Dynamic Search Using Entity Framework

I have a search screen with optional fields using Entity Framework, I want to build a dynamic query without selecting the object and filter on it.
I want to Optimize the following Existing Search, I don't want to select "var query = from p in context.APLCN_TRCKR select p;" at this stage because the application will be used by more than 100 people at once:
using (var context = new VASTEntities())
{
var query = from p in context.APLCN_TRCKR select p;
if (!string.IsNullOrEmpty(searchObj.CUST_NAME_X))
query = query.Where(p => p.CUST_NAME_X == searchObj.CUST_NAME_X.Trim());
if (!string.IsNullOrEmpty(searchObj.SURNM_X))
query = query.Where(p => p.CUST_SURNM_X == searchObj.SURNM_X.Trim());
if (!string.IsNullOrEmpty(searchObj.QUEUE_ID))
query = query.Where(p => p.QUEUE_ID == searchObj.QUEUE_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.BP_ID))
query = query.Where(p => p.BPID == searchObj.BP_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.UserID))
query = query.Where(p => p.CURR_OWNR_USER_ID == searchObj.UserID.Trim());
if (!string.IsNullOrEmpty(searchObj.APLCN_TRCKR_ID))
query = query.Where(p => p.APLCN_TRCKR_ID == searchObj.APLCN_TRCKR_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.APLCN_STTS_ID))
query = query.Where(p => p.APLCN_STTS_ID == searchObj.APLCN_STTS_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.CUST_ID))
query = query.Where(p => p.CUST_ID == searchObj.CUST_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.CELL_ID))
query = query.Where(p => p.CELL_ID == searchObj.CELL_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.ORIGN_ID))
query = query.Where(p => p.ORIGN_ID == searchObj.ORIGN_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.ORGTN_CHANL_ID))
query = query.Where(p => p.ORGTN_CHANL_ID == searchObj.ORGTN_CHANL_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.CR_DCSN_ID))
query = query.Where(p => p.CR_DCSN_ID == searchObj.CR_DCSN_ID.Trim());
if (!string.IsNullOrEmpty(searchObj.SBSA_CUST_I))
query = query.Where(p => p.SBSA_CUST_I == searchObj.SBSA_CUST_I.Trim());
if (!string.IsNullOrEmpty(searchObj.USER_ID_APP_CRTD))
query = query.Where(p => p.USER_ID_APP_CRTD == searchObj.USER_ID_APP_CRTD.Trim());
if (!string.IsNullOrEmpty(searchObj.RGION_ID))
{
int r = int.Parse(searchObj.RGION_ID.Trim());
query = query.Where(p => p.RGION_ID == r);
}
if (!string.IsNullOrEmpty(searchObj.CR_REGION))
{
int x = int.Parse(searchObj.CR_REGION);
if (x == 0)
{
// check 0 - not applicable or null
query = query.Where(p => p.CR_REGION_ID == 0 || p.CR_REGION_ID == null);
}
else
{
query = query.Where(p => p.CR_REGION_ID == x);
}
}
if (!string.IsNullOrEmpty(searchObj.Process_Type))
query = query.Where(p => p.PRCES_TYPE_ID == searchObj.Process_Type.Trim());
query.ToList();
foreach (var a in query)
{
searchAppsObj.Add(Translator.TranslateReqObjToBO.TranslateDTOToSearchApp(a));
}
if (query.Count() == 0)
{
throw new Exception("No Applications Found.");
}
context.Connection.Close();
return searchAppsObj;
}
I want to do something like this but this one is not working properly:
string cust_name_x = "", surname_x = "", queue_id = "", bp_id = "", user_id = "", aplcn_trckr_id = "",
aplcn_stts_id = "", cust_id = "", process_type = "", cr_region = "", cell_id = "", Origin = "", region = "", channel = "", credit_verdict = "", sbsa_cust_id = "", app_creator_id = "";
if (!string.IsNullOrEmpty(searchObj.CUST_NAME_X))
cust_name_x = searchObj.CUST_NAME_X.Trim();
if (!string.IsNullOrEmpty(searchObj.SURNM_X))
surname_x = searchObj.SURNM_X.Trim();
if (!string.IsNullOrEmpty(searchObj.QUEUE_ID))
queue_id = searchObj.QUEUE_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.BP_ID))
bp_id = searchObj.BP_ID;
if (!string.IsNullOrEmpty(searchObj.UserID))
user_id = searchObj.UserID.Trim();
if (!string.IsNullOrEmpty(searchObj.APLCN_TRCKR_ID))
aplcn_trckr_id = searchObj.APLCN_TRCKR_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.APLCN_STTS_ID))
aplcn_stts_id = searchObj.APLCN_STTS_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.CUST_ID))
cust_id = searchObj.CUST_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.Process_Type))
process_type = searchObj.Process_Type.Trim();
if (!string.IsNullOrEmpty(searchObj.CR_REGION))
cr_region = searchObj.CR_REGION.Trim();
if (!string.IsNullOrEmpty(searchObj.CELL_ID))
cell_id = searchObj.CELL_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.ORIGN_ID))
Origin = searchObj.ORIGN_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.RGION_ID))
region = searchObj.RGION_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.ORGTN_CHANL_ID))
channel = searchObj.ORGTN_CHANL_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.CR_DCSN_ID))
credit_verdict = searchObj.CR_DCSN_ID.Trim();
if (!string.IsNullOrEmpty(searchObj.SBSA_CUST_I))
sbsa_cust_id = searchObj.SBSA_CUST_I.Trim();
if (!string.IsNullOrEmpty(searchObj.USER_ID_APP_CRTD))
app_creator_id = searchObj.USER_ID_APP_CRTD.Trim();
using (var context = new VASTEntities())
{
var query = from p in context.APLCN_TRCKR
where
p.CUST_NAME_X.Contains(cust_name_x) &&
p.CUST_SURNM_X.Contains(surname_x) &&
p.QUEUE_ID.Contains(queue_id) &&
p.BPID.Contains(bp_id) &&
p.CURR_OWNR_USER_ID.Contains(user_id) &&
p.APLCN_TRCKR_ID.Contains(aplcn_trckr_id) &&
p.APLCN_STTS_ID.Contains(aplcn_stts_id) &&
p.CUST_ID.Contains(cust_id) &&
p.PRCES_TYPE_ID.Contains(process_type) &&
p.CELL_ID.Contains(cell_id) &&
SqlFunctions.StringConvert((double)p.CR_REGION_ID).Contains(cr_region) &&
p.ORIGN_ID.Contains(Origin) &&
SqlFunctions.StringConvert((double)p.RGION_ID).Contains(region) &&
p.ORGTN_CHANL_ID.Contains(channel) &&
p.CR_DCSN_ID.Contains(credit_verdict) &&
p.SBSA_CUST_I.Contains(sbsa_cust_id)
select p;
query.ToList();
if (query.Count() == 0)
{
throw new Exception("No Applications Found.");
}
foreach (var a in query)
{
searchAppsObj.Add(Translator.TranslateReqObjToBO.TranslateDTOToSearchApp(a));
}
context.Connection.Close();
return searchAppsObj;
}
You can just create a collection of lambda expression like below:
var filters = new List<Expression<Func<Application, bool>>>();
if (!string.IsNullOrWhitespace(searchObj.CUST_NAME_X))
filters.Add(application => application .CUST_NAME_X.Contains(searchObj.CUST_NAME_X.Trim());
if (!string.IsNullOrEmpty(searchObj.SURNM_X))
filters.Add(application => application .CUST_SURNM_X.Contains(searchObj.SURNM_X.Trim());
// And so on for all criteria
After that you can do a loop on filters like below:
using (var context = new VASTEntities())
{
var query = context.APLCN_TRCKR;
foreach(var filter in filters)
{
query = query.Where(filter);
}
var result = query.ToList();
if (result.Count() == 0)
{
throw new Exception("No Applications Found.");
}
foreach (var a in result)
{
searchAppsObj.Add(Translator.TranslateReqObjToBO.TranslateDTOToSearchApp(a));
}
context.Connection.Close();
return searchAppsObj;
}
change
var query = from p in context.APLCN_TRCKR select p;
to
var query = context.APLCN_TRCKR.AsQueryable();
And when the filtering work is done:
await query.ToListAsync() // this one goes to the database
Also have a look at this: Linq query filtering
In Addition: don't call context.Connection.Close(); as this is going to be executed anyway because using behaves like try { ... } finally { // dispose work }

EF other way to Sum() new Column

i got stuck on this query that calculate the new column.
i cannot explain briefly just see the snippet code below.
from user in context.Table
select new
{
Total = user.Total,
Paid = user.Paid,
Balance = //should be Total - Paid to assign result
}
i have tried this query
var result = from a in context.EnrollmentRequests
where a.SchoolYear == SchoolYear
select new
{
a.StudentID,
Name = a.Student.FirstName + " " + a.Student.MiddleName + " " + a.Student.LastName,
Tuition = context.Miscs.Where(m => m.YearLevel == a.YearLevel && m.SchoolYear == SchoolYear && m.Term == a.Term && m.CourseID == a.CourseID)
.Select(ms => new { Amount = ms.Amount })
.Union(context.StudentCharges
.Where(s => s.YearLevel == a.YearLevel && s.SchoolYear == SchoolYear && s.Term == a.Term && s.CourseID == a.CourseID && s.StudentID == a.StudentID)
.Select(ss => new { Amount = ss.Amount }))
.Union(context.StudentSubjectTakes
.Where(st => st.StudentID == a.StudentID && st.SchoolYear == a.SchoolYear && st.Term == a.Term && st.YearLevel == a.YearLevel && st.EducationalLevel == a.Student.StudentAdvanceEducations.FirstOrDefault().EducationLevel)
.Select(st => new
{
Amount = context.SubjectOfferedFees
.Where(f => f.SubjectsOfferedID == st.SubjectsOfferedID).Sum(w => (decimal?)w.Cost ?? 0)
}))
.Select(f => f.Amount).Sum(),
PaymentMade = context.Payments.Where(p => p.SchoolYear == SchoolYear && p.Term == a.Term && p.StudentID == a.StudentID && p.PaymentDes == "Tuition Fee").Sum(sm => (decimal?)sm.Amount),
Balance = Tuition - PaymentMade //Does not exist on current context
};
but doesn't work it says that does not exist on current context.
how could this possible.
thanks. this will be helpful to anyone.
Balance = user.Total - user.Paid

How can I access other then the "General" attributes of a Entity-Property from a EntityModel within a T4?

I am using sort of the following code to get all properties of a entity
IList<EdmProperty> list = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity)
Then I iterate through these list, access each Property and read the Property Properties (Yeah, much properties, hope no one gets to confused).
While I can easily access the General attributes I don't know how to access the other Properties of the the Entity-Property like Max Length & Fixed Length
Those properties are not part of PrimitiveType. They are directly in p.TypeUsage under Facets property.
Try the following code:
var MaxLength = (property as EdmMember).TypeUsage.Facets.Where(f => f.Name == "MaxLength").SingleOrDefault();
int maxLength = -1;
if(MaxLength != null)
maxLength = (int)MaxLength.Value;
You can use the maxLength variable in the template code. Any other facet can be accessed in a similar way.
protected void RecognizeByMetadata(IList<Facet> facets)
{
//Dictionary<string, string> attributes = new Dictionary<string, string>();
//facets.AsParallel().ForAll(x => attributes.Add(x.Name, x.Value + ""));
try{
var t = facets.Where(x => x.Name == "MaxLength").Select(x => x.Value).FirstOrDefault();
if (t != null)
{
string typ = t.GetType().FullName;
this.isMax = (t.ToString() == "Max");
if (!isMax)
this.MaxLength = (int?)t;
}
else
{
isMax = false;
MaxLength = null;
}
this.IsNullable = (bool?)facets.Where(x => x.Name == "Nullable").Select(x => x.Value).FirstOrDefault();
this.Defaultvalue = facets.Where(x => x.Name == "DefaultValue").Select(x => x.Value).FirstOrDefault();
this.IsUnicode = (bool?)facets.Where(x => x.Name == "Unicode").Select(x => x.Value).FirstOrDefault();
this.IsFixedlength = (bool?)facets.Where(x => x.Name == "FixedLength").Select(x => x.Value).FirstOrDefault();
//string precision = facets.Where(x => x.Name == "Precision").Select(x => x.Value + "").FirstOrDefault();
//string scale = facets.Where(x => x.Name == "Scale").Select(x => x.Value + "").FirstOrDefault();
isRecognized = true;
recognizeUnique();
} catch (Exception e)
{
string mewssage = e.Message;
throw;
}
}