Adding additional linq where clauses based on variables - c#

I'm trying to add additional where clauses to a linq query depending on what variable results are passed to a function.
var allFeedback =
from f in _unitOfWork.Feedback.All()
join b in _unitOfWork.Bookings.All() on f.CourseBookingID equals b.CourseBookingID
join cb in _unitOfWork.CourseBookings.All() on f.CourseBookingID equals cb.CourseBookingID
where b.SiteID == siteID && b.Date >= fromDate && b.Date <= to && b.CancelledID == null
select f;
if (courseID > 0)
{
allFeedback.Where(f => f.CourseBooking.CourseID == courseID);
}
if (facilitatorID == 0)
{
allFeedback.Where(f => f.CourseBooking.FacilitatorID == null);
}
else if (facilitatorID > 0)
{
allFeedback.Where(f => f.CourseBooking.FacilitatorID == facilitatorID);
}
allFeedback.ToList();
I want to add the where clauses to the original query "allFeedback" but when the query is executed the additional clauses are ignored.
Is this possible?

yes its possible just do :
if (courseID > 0)
{
allFeedback = allFeedback.Where(f => f.CourseBooking.CourseID == courseID);
}
if (facilitatorID == 0)
{
allFeedback = allFeedback.Where(f => f.CourseBooking.FacilitatorID == null);
}
else if (facilitatorID > 0)
{
allFeedback = allFeedback.Where(f => f.CourseBooking.FacilitatorID == facilitatorID);
}
You just forgot to assign the result to the variable.

Related

IQueryable Adding OR Conditions to the chain of queries

How can i Chain EF queries with OR condition
Right now i am chaining or building the query like below and this is ended up adding AND conditions
if (model.EMailChoices?.Count() > 0)
{
query = query.Where(
c => model.EMailChoices.Contains(c.Contact.CommunicationPreferences.TPEMail)
);
}
if (model.MailChoices?.Count() > 0)
{
query = query.Where(
c => model.MailChoices.Contains(c.Contact.CommunicationPreferences.TPMail)
);
}
if (model.PhoneChoices?.Count() > 0)
{
query = query.Where(
c => model.PhoneChoices.Contains(c.Contact.CommunicationPreferences.TPTelephone)
);
}
How can we add OR conditions to this chain
bool anyEmails = model.EMailChoices?.Any() == true;
bool anyMails = model.MailChoices?.Any() == true;
bool anyPhones = model.PhoneChoices?.Any() == true;
if(anyEmails || anyMails || anyPhones)
{
query = query.Where(
c => (anyEmails && model.EMailChoices.Contains(c.Contact.CommunicationPreferences.TPEMail))
|| (anyMails && model.MailChoices.Contains(c.Contact.CommunicationPreferences.TPEMail))
|| (anyPhones && model.PhoneChoices.Contains(c.Contact.CommunicationPreferences.TPTelephone)));
}

LINQ using Contains with entity

Am using ASP.NET MVC 5 to create an Application for billing, now i have thing function which receive a filter object with different variables, am having a problem with contains when i search, what am i doing wrong
public static List<Quote> getCustomerQuotes(QuoteFilter filter)
{
using (var db = new AppDBContext())
{
var q = db.Quotes.Where(u => u.entryDate > 0); ;
if (filter.type != null)
{
q = q.Where(u => u.quoteType == filter.type);
}
if (filter.only_permitable != null)
{
q = q.Where(u => !Values.NON_PERMITABLE_QUOTES.Contains(u.quoteType));
}
if (filter.quote_status != null)
q = q.Where(u => u.quote_status == (int)filter.quote_status);
if (filter.quotenumber != null)
{
q = q.Where(u => u.quote_number.Contains(filter.quotenumber));
}
if (filter.permitnumber != null)
q = q.Where(u => u.permit_number.Contains(filter.permitnumber));
if (filter.permit_status != null)
q = q.Where(u => u.permit_status == (int)filter.permit_status);
if (filter.quoteId != null)
q = q.Where(u => u.Id == (int)filter.quoteId);
if (filter.customer_id != null)
q = q.Where(u => u.customer_id == (int)filter.customer_id);
q = q.OrderByDescending(u => u.Id);
FileLogger.Log("getCustomerQuotes", q.ToString());
return q.ToList();
}
}
When i call the function and pass quotenumber, the contains doesnt search, it returns nothing
You have to evaluate your expression, before you apply the OrderByDescending.
q = q.Where(u => u.quote_number.Contains(filter.quotenumber)).ToList();
This should be happen also to the rest places.
Is quote number alpha-numeric? If yes, as Contains is case sensitive can you try comparison by first turning source and target to same case ? like
q = q.Where(u => u.quote_number.ToLower().Contains(filter.quotenumber.ToLower()));
Cheers
Ok, am answering my own question after finding a solution or i may call it a hack
public static List<Quote> getCustomerQuotes(QuoteFilter filter)
{
using (var db = new AppDBContext())
{
var q = db.Quotes.Where(u =>
(filter.type != null ? u.quoteType == filter.type : u.quoteType > 0) &&
(filter.only_permitable != null ? !Values.NON_PERMITABLE_QUOTES.Contains(u.quoteType) : u.permitType > 0) &&
(filter.quote_status != null ? u.quote_status == filter.quote_status : u.quote_status > -100) &&
(!string.IsNullOrEmpty(filter.quotenumber) ? u.quote_number.Contains(filter.quotenumber) || u.groupName.Contains(filter.quotenumber) : u.quoteType > 0) &&
(!string.IsNullOrEmpty(filter.permitnumber) ? u.permit_number.Contains(filter.permitnumber) || u.groupName.Contains(filter.permitnumber) : u.quoteType > 0) &&
(filter.permit_status != null ? u.permit_status == filter.permit_status : u.quoteType > 0) &&
(filter.quoteId != null ? u.Id == filter.quoteId : u.Id > 0) &&
(filter.customer_id != null ? u.customer_id == filter.customer_id : u.customer_id > -1)
).OrderByDescending(u => u.Id);
//FileLogger.Log("getCustomerQuotes", q.ToString());
return q.ToList();
}
}
i dont know why it didn't work the first time but now it works.

C# use left outer join in LINQ

This is my method:
public IEnumerable<Web_Vendor> GetSaleBrands()
{
using (var _db = new LuxedecorContext())
{
IQueryable<Web_Vendor> web_vendors = _db.Web_Vendor.
Where(x =>
(_db.Web_Promotion.Where(z => z.VendorID != string.Empty
&& z.Static == true && z.Percent != 0 &&
(x.WebPromotion.Expires >= DateTime.Now || x.WebPromotion.Expires == null))
.Select(r => r.VendorID).Contains(x.VendorID))
||
(_db.NavItems.Where(y => x.WebPromotion.VendorID == y.SC1
&& !(y.Promotion == "" || y.Promotion == null)
&& (y.PromotionStart <= DateTime.Now) && (y.PromotionEnd >= DateTime.Now || y.PromotionEnd == null))
.Select(g => g.SC1).Contains(x.WebPromotion.VendorID)))
.Where(x => x.Active == true).OrderBy(x => x.NameExtra)
.ThenBy(x => x.Sequence);
var a = web_vendors.ToList(); // 16 values
var b = web_vendors.Include(x => x.WebPromotion).ToList(); // 13 values
}
throw new NotImplementedException();
}
I need to Include nullable values to my collection of Web_Vendors. I know, it's famous question, but I need to return collection of Web_Vendors instead of collection of dynamic types. Is it possible?

How to write below sql query in linq c# where some of paramteres will be null sometimes

I have following query in sql,
select * from dbo.WaitingLists
where WaitingListTypeId in (1)
or StakeBuyInId in (Select StakeBuyInId from dbo.WaitingLists where StakeBuyInId in (5) and
WaitingListTypeId = 2)
in this, sometimes StakeBuyInId will be null or WaitingListTypeId will ne null. I want to perform this query via linq c# in following code.
public GameListItem[] GetMyWaitingList(Guid UserId, int LocalWaitingListTypeId, int GlobalWaitingListTypeId, int[] StakeBuyInIds)
{
ProviderDB db = new ProviderDB();
List<GameListItem> objtempGameListItem = new List<GameListItem>();
List<GameTables> objGameTablesList = new List<GameTables>();
var objWaitingListUser = db.WaitingLists.Where(x => x.UserId.Equals(UserId));
if (LocalWaitingListTypeId > 0 || (GlobalWaitingListTypeId > 0 && StakeBuyInIds != null))
{
objWaitingListUser = objWaitingListUser.Where(x => x.WaitingListTypeId == LocalWaitingListTypeId || (x.WaitingListTypeId == GlobalWaitingListTypeId
&& StakeBuyInIds != null ? StakeBuyInIds.Contains((Int32)x.StakeBuyInId) : true)
);
}
return objtempGameListItem.ToArray();
}
Here StakeBuyInIds int[] will be sometimes null, then how will i perform linq operation for above sql query. Thanks for any help.
You could probably just check for null outside of your expression, like this:
if (LocalWaitingListTypeId > 0 || (GlobalWaitingListTypeId > 0 && StakeBuyInIds != null))
{
if (StakeBuyInIds != null)
{
objWaitingListUser = objWaitingListUser.Where(
x => x.WaitingListTypeId == LocalWaitingListTypeId ||
(x.WaitingListTypeId == GlobalWaitingListTypeId &&
StakeBuyInIds.Contains((Int32)x.StakeBuyInId));
} else {
objWaitingListUser = objWaitingListUser.Where(
x => x.WaitingListTypeId == LocalWaitingListTypeId ||
x.WaitingListTypeId == GlobalWaitingListTypeId);
}
}
You might also be able to do this:
if (LocalWaitingListTypeId > 0 || (GlobalWaitingListTypeId > 0 && StakeBuyInIds != null))
{
var arrayNull = StakeBuyInIds != null;
var array = StakeBuyInIds ?? new int[0];
objWaitingListUser = objWaitingListUser.Where(
x => x.WaitingListTypeId == LocalWaitingListTypeId ||
(x.WaitingListTypeId == GlobalWaitingListTypeId &&
(arrayNotNull || array.Contains((Int32)x.StakeBuyInId)));
}
It effect it tests for null outside of the query, but ensures that it cannot be null when actually executing the query.
The waitingListTypeId and stakeBuyinId should be nullable int in your relational object WaitingList.
List<int?> WaitingListTypeIds=new List(new int?[]{1});
var StakeBuyInIds=from w in WaitingListsCollection where new List<int?>(new int?[]{5}).Contains(w.StakeBuyInId) && w.WaitingListTypeId = 2;
var output= from w in WaitingListsCollection where WaitingListTypeIds.Contains(w.WaitingListTypeId) || StakeBuyInIds.Contains(w.StakebuyInId)

How can i use "COALESCE(SUM..." in linq?

i try to use sum and Coalesce . How can i translate to linq?
SELECT #SumQtyOut=COALESCE(SUM(Qty),0) FROM dbo.StockMovement WHERE FromLocationType=#FromLocationType AND
* FromNo=#FromNo AND FromSeq=#FromSeq AND ItemTypeNo=#ItemTypeNo AND ItemID=#ItemID
i do sometihng :
using (StockProcedureDataContext stock = new StockProcedureDataContext())
{
SumQtyOut = from s in stock.StockMovements
where s.FromLocationType == FromLocationType &&
s.FromNo== FromNo &&
s.FromSeq == FromSeq &&
s.ItemTypeNo == ItemTypeNo &&
s.ItemID == ItemID select
}
This snippet should yield the result you are looking for.
using (StockProcedureDataContext stock = new StockProcedureDataContext())
{
var items = from s in stock.StockMovements
where s.FromLocationType == FromLocationType &&
s.FromNo== FromNo &&
s.FromSeq == FromSeq &&
s.ItemTypeNo == ItemTypeNo &&
s.ItemID == ItemID
select s.Qty ?? 0;
SumQtyOut = items.Sum(x => x);
}
select s.Qty ?? 0 returns 0 if s.Qty is null. items.Sum(x => x) summs up the quantities you have selected.

Categories

Resources