Dropping columns from a where clause can i use the ? operator - c#

I cannot help but feel this is very slopy and there is more that I can do to cut this down.
public async Task<IActionResult> Index(int? id)
{
List<ClubMembers> clubs = new List<ClubMembers>();
Guid.TryParse(UserId.ToString().ToUpper(), out
Guid guidResult);
if (id == null)
clubs = await _context.ClubMembers.Where(w =>
w.isActive == true && w.isDeleted == false)
.Include(c => c.Role)
.Include(c => c.User)
.Where(w => w.isActive == true
&& w.isDeleted == false).ToListAsync();
else
clubs = await _context.ClubMembers.Where(w =>
w.ClubId == id && w.isActive == true && w.isDeleted
== false).Include(c => c.Role).Include(c => c.User)
.Where(w => w.isActive == true
&& w.isDeleted == false).ToListAsync();
ClubMembersViewModal clubMembersViewModal = new ClubMembersViewModal();
clubMembersViewModal.Clubusers = clubsMembers;
clubMembersViewModal.ClubInvitesViewModal = new ClubInvitesViewModel();
clubMembersViewModal.ClubInvitesViewModal.ClubId = ClubId;
clubMembersViewModal.ClubInvitesViewModal.FromMember = Email;
clubMembersViewModal.ClubInvitesViewModal.ToMember = "test#gmail.com";
return View(clubMembersViewModal);
}
As I am just removing the need for one column the w.ClubId == in the first query is their not a cleaner way of just removing the column from the one query at all seems sloppy to do it this way?.
Could I use the null check operation ? in some where as part of the where clause? I just want it to not filter ClubId if no id is passed.

You can use IQueryable<T> to construct your query step by step, like this.
IQueryable<ClubMembers> queryable = _context.ClubMembers
.Where(w => w.isActive == true && w.isDeleted == false)
.Include(c => c.Role).Include(c => c.User);
if (id != null)
queryable = queryable.Where(w => w.ClubId == id);
clubs = await queryable.ToListAsync();

Related

LINQ Query if condition external parameter

I'm trying to use LINQ to get a list of values.
I have code like this:
var _context = _scope.ServiceProvider.GetRequiredService<VMContext>();
if (boolparameter)
{
var listCE = _context.Ce
.Where(x => x.VuId == element.VuId)
.Where(x => x.Score == 8)
.AsNoTracking()
.ToList();
}
else
{
var listCE = _context.Ce
.Where(x => x.VuId == element.VuId)
.AsNoTracking()
.ToList();
}
Depends on boolparameter, I do a query or another one. Is there a way to use a single query with a conditions inside?
Something like:
var listCE = _context.Ce
.Where(x => x.VuId == element.VuId)
.Where(x => boolparameter ? x.Score == 8 : true)
.AsNoTracking()
.ToList();
C# Asp.NetCore SqlServer 2019
Thanks a lot!
You could try the following code if it works:
var listCE = _context.Ce
.Where(x => x.VuId == element.VuId)
.Where(x => !boolparameter || x.Score == 8)
.AsNoTracking()
.ToList();
Which means if boolparameter is false, x.Score doesn't matter, since !false would equal to true and it satisfies OR condition. Likewise if boolparameter is true, then x.score will also be checked if it is equal to 8.
Or maybe with one Where condition:
var listCE = _context.Ce
.Where(x => x.VuId == element.VuId && (!boolparameter || x.Score == 8))
.AsNoTracking()
.ToList();
var listCE = _context.Ce
.Where(x =>
x.VuId == element.VuId
&& (!boolparameter || x.Score == 8))
.AsNoTracking()
.ToList();
This checks whether boolparameter is true before checking x.Score.
Can you check that below?
var listCE = _context.Ce
.Where(x => boolparameter == false ? x.VuId == element.VuId :
(x.VuId == element.VuId &&
x.Score == 8))
.AsNoTracking()
.ToList();
This way is more verbose, but if you have more (or complicated) conditions it can be easier to read and quickly understand what affects the query.
LINQ doesn't execute the query until you reach .ToList() or otherwise try to access the result from the query.
This means you don't need to have the full query duplicated in both the if and else part:
var _context = _scope.ServiceProvider.GetRequiredService<VMContext>();
var listCEQuery = _context.Ce.Where(x => x.VuId == element.VuId)
// LINQ will append this to the initial where clause
if (boolparameter == true)
listCEQuery = listCEQuery.Where(x => x.Score == 8)
var listCE = listCEQuery.AsNoTracking().ToList();

Is there a way to set this entity/linq query to IEnumerable?

I'm trying to return an IEnumerable activities instead of "var"
var activities = ctx.Activities.Where(a => a.SiteID == propID)
.Where(a => a.ActivityTypeName == "Call")
.Select(x => new
{
x.DateTimeEntry,
x.Contact.OwnerContact.ParcelDatas
.FirstOrDefault(a => a.OwnerContactID == x.Contact.OwnerContact.OOwnerID)
.Parcel_LetterTracking.LMailDate,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID)
.FAQ_Library.FaqNum,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID)
.FAQ_Library.Question
});
edit: data type Object compiles but I'm not sure if that's right.
.Select already returns a an IEnumerable<TResult> also combine your ..where() clauses with && instead. https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netframework-4.8 also one other thing you can do is use .AsEnuemerable()
var activities = ctx.Activities.Where(a => a.SiteID == propID && a.ActivityTypeName == "Call")
.Select(x => new
{
x.DateTimeEntry,
x.Contact.OwnerContact.ParcelDatas.FirstOrDefault(a => a.OwnerContactID == x.Contact.OwnerContact.OOwnerID).Parcel_LetterTracking.LMailDate,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID).FAQ_Library.FaqNum,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID).FAQ_Library.Question
}).AsEnumerable();

Two dbcontexts cause an error "value cannot be null. parameter name entitytype"

I have 2 DbContexts in my application, and need to do a join in 2 tables that are each one in a different DbContext; I get this error
value cannot be null. parameter name entitytype
When I try to join 2 tables of the same context, this error does not happen.
var VerificaExistenciaSinistro = sinistroContext.SnsAviso
.Join(
sinistroContext.SnsNumAviso,
sinistro => sinistro.NumApo,
aviso => aviso.NumApo,
(sinistro, aviso) => new {
sinistroV = sinistro,
avisoV = aviso })
.Where(c => c.sinistroV.CodItm == c.avisoV.CodItm &&
c.sinistroV.NumApo == c.avisoV.NumApo &&
c.sinistroV.NumAvs == c.avisoV.SeqNumAvs)
.Join(sgsContext.EmsEmissao,
sinistro1 => sinistro1.sinistroV.CodCtrtAvs,
emissao => emissao.CodCtrt,
(sinistro1, emissao) => new {
sinistroC = sinistro1,
emissaoC = emissao })
.Where(c => c.sinistroC.sinistroV.CodCtrtAvs == c.emissaoC.CodCtrt &&
c.emissaoC.CodEmis == c.sinistroC.avisoV.CodEms)
.Where(x => x.sinistroC.sinistroV.NumApo == apolice &&
x.emissaoC.StsEmis == emissao &&
x.emissaoC.NumEndosso ==endosso &&
x.sinistroC.sinistroV.CodItm == cod_itm &&
x.sinistroC.sinistroV.CodCbe == cbeCod)
.Select(x => x.sinistroC)
.ToList();
It generally occurs when u query data from two dbcontext using IQueryable
I encountered the same issue when I was using two dbContext. The solution which I found was. If u are using join between two tables then load any one table's data first to a variable/Object so that It becomes IEnumerable or IList and then do join with that variable/Object to the another table of another dbContext
Example
var FirstDbContextTable = sinistroContext.SnsAviso
.Join(
sinistroContext.SnsNumAviso,
sinistro => sinistro.NumApo,
aviso => aviso.NumApo,
(sinistro, aviso) => new {
sinistroV = sinistro,
avisoV = aviso })
.Where(c => c.sinistroV.CodItm == c.avisoV.CodItm &&
c.sinistroV.NumApo == c.avisoV.NumApo &&
c.sinistroV.NumAvs == c.avisoV.SeqNumAvs).ToList();
var result=FirstDbContextTable.Join(sgsContext.EmsEmissao,
sinistro1 => sinistro1.sinistroV.CodCtrtAvs,
emissao => emissao.CodCtrt,
(sinistro1, emissao) => new {
sinistroC = sinistro1,
emissaoC = emissao })
.Where(c => c.sinistroC.sinistroV.CodCtrtAvs == c.emissaoC.CodCtrt &&
c.emissaoC.CodEmis == c.sinistroC.avisoV.CodEms)
.Where(x => x.sinistroC.sinistroV.NumApo == apolice &&
x.emissaoC.StsEmis == emissao &&
x.emissaoC.NumEndosso ==endosso &&
x.sinistroC.sinistroV.CodItm == cod_itm &&
x.sinistroC.sinistroV.CodCbe == cbeCod)
.Select(x => x.sinistroC)
.ToList();

can i make a this linq statement iteration from a collection in a single statement?

bool isExist = objCustomization.CustomSettings.Where(p => p.CustomizationType == selCustomizationType && p.CategoryID == selCategoryID).Any();
if (isExist)
{
chkFixLimit.Checked = objCustomization.CustomSettings.Where(p => p.CustomizationType == selCustomizationType && p.CategoryID == selCategoryID).FirstOrDefault().IsDefaultLimit;
}
else chkFixLimit.Checked = false;
Default value for boolean is false so you even don't need any conditions - just select first or default IsDefaultLimit value:
chkFixLimit.Checked =
objCustomization.CustomSettings
.Where(p => p.CustomizationType == selCustomizationType && p.CategoryID == selCategoryID)
.Select(p => p.IsDefaultLimit)
.FirstOrDefault();
UPDATE (answer for your comment) in case you have non-boolean value or default value (zero for integer) do not fit your requirements, with DefaultIfEmpty you can provide own default value if there is no items matching your condition:
maxCountCmb.SelectedIndex =
objCustomization.CustomSettings
.Where(p => p.CustomizationType == selCustomizationType && p.CategoryID == selCategoryID)
.Select(p => p.DefaultFreeCount)
.DefaultIfEmpty(-1)
.First();
Sure you can:
var item = objCustomization.CustomSettings.FirstOrDefault(p => p.CustomizationType == selCustomizationType && p.CategoryID == selCategoryID);
chkFixLimit.Checked = item != null && item.IsDefaultLimit;
Or single statement, as you wish:
chkFixLimit.Checked = new Func<bool>(() => {
var item = objCustomization.CustomSettings.FirstOrDefault(p => p.CustomizationType == selCustomizationType && p.CategoryID == selCategoryID);
return item != null && item.IsDefaultLimit;
}).Invoke();
chkFixLimit.Checked = objCustomization.CustomSettings
.Where(p => p.CustomizationType == selCustomizationType
&& p.CategoryID == selCategoryID)
.Select(c => c.IsDefaultLimit)
.FirstOrDefault();
This not in one line but it is more readable, you can change:
var setting = objCustomization.CustomSettings
.FirstOrDefault(p => p.CustomizationType == selCustomizationType
&& p.CategoryID == selCategoryID);
chkFixLimit.Checked = setting == null ? false : setting.IsDefaultLimit;
That code is more-or-less the use case of the FirstOrDefault method. If something exists, return the first such item, and return a default value (null for reference types) if it doesn't. So you could just do:
var item = objCustomization.CustomSettings.FirstOrDefault
(p => p.CustomizationType == selCustomizationType && p.CategoryID)
and as result, the item object will either be null (assuming you indeed work with a reference type), or it will have a value.
After that you can just check that, with a simple
chkFixLimit.Checked = (item == null) ? false : item.IsDefaultLimit;

Cannot implicitly convert type System.Collections.Generic.IEnumerable<> to bool

I'm developing an ASP.NET MVC 4 Application and I'm trying to run this Lambda expression in Entity Framework 5.
var customer = db.GNL_Customer.Where(d => d.GNL_City.FKProvinceID == advancedProvinceID || advancedProvinceID == null)
.Where(d => d.FKCityID == advancedCityID || advancedCityID == null)
.Where(d => d.FKDepartmentStoreID == advancedDepartmentStoreID || advancedDepartmentStoreID == null)
.Where(d => d.GNL_CustomerLaptopProduct.Where(r => String.Compare(r.BrandName, brandID) == 0 || brandID == null));
I get this error :
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<ITKaranDomain.GNL_CustomerLaptopProduct>' to 'bool'
I know that the last where clause is wrong but I don't know how to correct it.
You might want another .Any instead of a .Where in your .Any clause at the end:
var customer = db.GNL_Customer.Where(d => d.GNL_City.FKProvinceID == advancedProvinceID || advancedProvinceID == null)
.Where(d => d.FKCityID == advancedCityID || advancedCityID == null)
.Where(d => d.FKDepartmentStoreID == advancedDepartmentStoreID || advancedDepartmentStoreID == null)
.Any(d => d.GNL_CustomerLaptopProduct.Any(r => String.Compare(r.BrandName, brandID) == 0 || brandID == null));
Use Where ( Any ) in last statement to select customers which have at least one product satisfying your conditions:
var customer = db.GNL_Customer
.Where(d => d.GNL_City.FKProvinceID == advancedProvinceID || advancedProvinceID == null)
.Where(d => d.FKCityID == advancedCityID || advancedCityID == null)
.Where(d => d.FKDepartmentStoreID == advancedDepartmentStoreID || advancedDepartmentStoreID == null)
.Where(d => brandID == null || d.GNL_CustomerLaptopProduct.Any(r => r.BrandName == brandID));

Categories