linq - include where parameters - c#

I have a strange question about Linq.
I have this query:
var results = (from p in hotsheetDB.Properties
where p.PCode == pCode
&& p.PropertyStatusID == propertyStatuses
orderby p.PropertyID descending
select new
{
PropertyId = p.PropertyID,
PCode = p.PCode,
PropertyTypeName = p.cfgPropertyType.Name,
FullAddress = p.Address1 + " " + p.Address2,
ZipCode = p.ZipCode.Code,
CityName = p.cfgCity.Name,
LivingSquareFeet = p.LivingSquareFeet,
LotSquareFeet = p.LotSquareFeet,
NumBedrooms = p.NumBedrooms,
NumBathrooms = p.NumBathrooms,
PropertyStatusName = p.cfgPropertyStatuse.Name
});
You notice pCode and propertyStatuses parameters. They are input values from the users. He wants to search by pCode or/and by propertyStatuses.
So, when the user fills in only pCode he wants to return all the records with that pCode having ANY propertyStatuses...well, because propertyStatuses IS in the query but it's null, the query will not return anything (because there is no record with empty(null) propertyStatuses...
Therefore, the question: is there any way to include these where params only whey they have values? (without making separate N queries with all the combination? (I have multiple inputs)
Thanks in advance..

You could change your where clause to make the parts which include null always return true.
For example:
where (pCode == null || p.PCode == pCode)
&& (propertyStatuses == null || p.PropertyStatusID == propertyStatuses)

I'm only guessing here but try:
where p.PCode == pCode &&
(p.PropertyStatusID == null || p.PropertyStatusID == propertyStatuses)

Related

C# Linq Left Outer Join WHERE clause

I have a linq query where i'm trying to return data if the right Sales table doesn't have a record and also only if the Sales.Fallthrough == false && Sales.Date == null.
This is the base of my query and i've tried many different things with this but can't seem to get it to return the required data. Everything I try only seems to return records if there is no Sales OR they match the WERE caluse but not both.
from cr in efContext.Cases
join si in efContext.Sales on cr.CaseId equals si.CaseId into sicr
from sicr in (from si in sicr
where si == null
select si
).DefaultIfEmpty()
where cr.Withdrawn == false
select new
{
CaseId = cr.CaseId,
PropertyAddress = extension.PropertyAddressTownFormat(cr.PropertyAddress1, cr.PropertyTown),
TargetExchangeDate = sicr.TargetExchangeDate == null ? null : sicr1.TargetExchangeDate,
ActualExchangeDate = sicr.ActualExchangeDate,
}).ToList();
EDIT
Missed out a little information.
Also if there is a record in Sales but does not match WHERE clauses then still return the left side and the right side as if there wasn't a record.
Thanks.
Isn't it just...?
from cr in efContext.Cases
join si in efContext.Sales on cr.CaseId equals si.CaseId into sicr
from s in sicr.DefaultIfEmpty()
select new
{
CaseId = cr.CaseId,
PropertyAddress = extension.PropertyAddressTownFormat(cr.PropertyAddress1, cr.PropertyTown),
TargetExchangeDate = s == null || (s.Fallthrough == false && s.Date == null) ? null : s.TargetExchangeDate,
ActualExchangeDate = s == null || (s.Fallthrough == false && s.Date == null) ? null : s.ActualExchangeDate,
};
Please note that you cannot call to ToList since the query returns an anonymous type.

Order by with condition

I want to get the records with "Restricted" at top.
here Is my query:
var records = (from entry in db.Table1
orderby entry.Always_Prohibited
select new
{
RowID = entry.RowID,
VehicleMake = entry.Make,
VehicleModel = entry.Model,
Restricted = (entry.Always_Prohibited == null || entry.Always_Prohibited == "False") ? "Restricted" : "Not Restricted"
}).ToList();
I tried by Orderby but it is not working because entry.Always_Probibited is a string field.
Please suggest me.
If you have only two values, simply order descending:
from entry in db.Table1
orderby entry.Always_Prohibited descending
If you have more, assign integer values to your strings:
from entry in db.Table1
orderby entry.Always_Prohibited=="A" ? 0 : entry.Always_Prohibited=="B" ? 1 : 2 // and so on
As a side note, strings are a pretty terrible way of storing state in databases. You should redesign it to store it as well defined integers (preferably as foreign keys in master lookup tables, ie strongly typed enums).
User then below give code. It will help to you.
var records = (from entry in db.Table1.AsQueryable();
orderby entry.Always_Prohibited
select new
{
RowID = entry.RowID,
VehicleMake = entry.Make,
VehicleModel = entry.Model,
Restricted = (entry.Always_Prohibited == null || entry.Always_Prohibited == "False") ? "Restricted" : "Not Restricted"
}).ToList();

Build a Linq statement with IsNullOrEmpty check

How can I build a single Linq statement where it check returns all records unless the param is passed? If param is empty then ignore specific 'where'.
I have tried using IsNullOrEmpty within the WHERE but I get an error.
Here are the NON-REQUIRED form field for searching for Invoices.
Invoice Id, Check Number, State Issued
var invoices = ctx.Invoices; <-- get all invoiced
if (inputInvoiceId > 0)
invoices = from i in invoices
where i.id == inputInvoiceId
select i;
if (!string.IsNullOrEmpty(inputCheckNumber))
invoices = from i in invoices
where i.checkNumber == inputCheckNumber
select i;
if (!string.IsNullOrEmpty(inputState))
invoices = from i in invoices
where i.state == inputState
select i;
You could build your query by conditionally appending where clauses like this:
var invoices = ctx.Invoices.AsQueryable();
if (inputInvoiceId > 0)
invoices = invoices.Where(x => x.id == inputInvoiceId);
if (!string.IsNullOrEmpty(inputCheckNumber))
invoices = invoices.Where(x => x.checkNumber == inputCheckNumber);
if (!string.IsNullOrEmpty(inputState))
invoices = invoices.Where(x => x.state == inputState);
return invoices.ToList();
Each additional where clause further filters your results, but the query itself won't be executed (nor any data retrieved) until you call ToList().
What #GrantWinney said will work. Alternatively, you can deal with it in a single query, which may or may not have query compilation/cache benefits if you are concerned about such things:
// Query short-circuit parameters
var invoiceNotSpecified = inputVoiceId == 0;
var checkNumberNotSpecificed = String.IsNullOrEmpty(inputCheckNumber);
var stateNotSpecified = String.IsNullOrEmpty(inputState);
// Query
var invoices = from i in ctx.Invoices
where (invoiceNotSpeficied || i.id == inputInvoiceId) &&
(checkNumberNotSpecified || i.checkNumber == inputCheckNumber) &&
(stateNotSpecified || i.state == inputState)
select i;

Optimizing A LINQ To Objects Query

I'm trying to optimize the below LINQ query to improve it's speed performance. The number of objects it's searching against could be in the tens of thousands.
var lQuery = from o in oEvents
where (o.oSalesEvent != null && o.oSalesEvent.OccurDate < oCalcMgr.OccurDate && (
(oCalcMgr.InclTransTypes == Definitions.TransactionTypes.SalesAll) ?
(o.oSalesEvent.EventStateID == ApprovedID || o.oSalesEvent.EventStateID == PendingID) :
o.oSalesEvent.EventStateID == ApprovedID)) &&
((oCalcMgr.InclTransTypes == Definitions.TransactionTypes.SalesAll) ?
(o.oSalesMan.oEmployment.EventStateID == ApprovedID || o.oSalesMan.oEmployment.EventStateID == PendingID) :
o.oSalesMan.oEmployment.EventStateID == ApprovedID)
select new { SaleAmount = o.SaleAmount.GetValueOrDefault(), CompanyID = o.oSalesEvent.CompanyID };
The query basically says, give me the sales amounts and company ids from all sale events that occurred prior to a certain date. The sale event's status and the salesman's employment status should either always be "approved" or they can be also "pending" if specified.
As you can see there's a date comparison and a couple of integer comparisons. Which integer comparison used is based on whether or not a property matches a certain Enum value.
I have some ideas of my own on ways to go about the optimization, but I want to hear others thoughts, who might have more insight into how LINQ would translate this query behind the scenes.
Thanks
It seems to me that your biggest challenge is that you're doing multiple criteria checks in your Linq statement that will take alot of time.
What about creating a new property in oEvents - Say "IsEligable" and set it's value within the Set statements of your other variables (much faster than constant re-querying of each variable in the Linq).
Then, by the time you get to this part of your code, you could update your Linq to be something along the lines of:
var lQuery = from o in oEvents
where (o.oSalesEvent != null && o.oSalesEvent.OccurDate < oCalcMgr.OccurDate && o.IsEligable == True)
select new { SaleAmount = o.SaleAmount.GetValueOrDefault(), CompanyID = o.oSalesEvent.CompanyID };
... I'm guessing that would speed up the execution, but just a thought...
This is as much to improve readability as to possibly speed it up, but give this a try:
var lQueryTemp = from o in oEvents
where (o.oSalesEvent != null && o.oSalesEvent.OccurDate < oCalcMgr.OccurDate)
if (oCalcMgr.InclTransTypes == Definitions.TransactionTypes.SalesAll)
{
lQueryTemp = from o in lQueryTemp
where (o.oSalesEvent.EventStateID == ApprovedID || o.oSalesEvent.EventStateID == PendingID) &&
(o.oSalesMan.oEmployment.EventStateID == ApprovedID || o.oSalesMan.oEmployment.EventStateID == PendingID);
}
else
{
lQueryTemp = from o in lQueryTemp
where (o.oSalesEvent.EventStateID == ApprovedID && o.oSalesMan.oEmployment.EventStateID == ApprovedID);
}
var lQuery = from o in lQueryTemp
select new { SaleAmount = o.SaleAmount.GetValueOrDefault(), CompanyID = o.oSalesEvent.CompanyID };
This might speed it up by pulling out both checks of oCalcMgr.InclTransTypes, which is effectively a constant for purposes of this query.

linq query with condition

I'm writing a linq query in query syntax and I'm wondering how to add another where clause.
Basically, I have the following:
var test = from t in MyDC.TheTable
where t.UserID == TheUserID
where t.DateDone.Date == TheDate.Date
select new MyModel {.....};
TheTable has a column called LinkedID and this column is also in another table called ColorStatus (a number between 1 and 10). I'm looking to write the where clause "where the LinkedID in the ColorStatus table is less than 7".
Thanks.
Just a suggestion on improving the statement you have. You can actually merge the two where conditions into a single one. && means "AND"
Where t.UserID == TheUserID && t.DateDone.Date = TheDate.Date
Your information "another table called ColorStatus" doesn't make sense here.
var test = from t in MyDC.TheTable
where t.UserID == TheUserID
&& t.DateDone.Date == TheDate.Date
&& t.LinkedID < 7
select new MyModel {.....};
Probably I didn't get your idea, here is an example of join may help you.
var test = from t in MyDC.TheTable
join x in MyDC.ColorStatus
on t.LinkedID == x.LinkedID
where t.UserID == TheUserID
&& t.DateDone.Date == TheDate.Date
&& x.AnotherField == 1
select new MyModel {.....};

Categories

Resources