Using multiple Filters in Query - sap-cloud-sdk

Is there a way to add multiple filters to a query based on a condition to the Query Expression.
For eg something along the lines of.
AddressFluentHelper queryHelper=service.getAllAddress;
if(zipCode!=null){
queryHelper.filter(Address.ZIPCODE.eq(zipCode))
}
if(street!=null){
queryHelper.filter(Address.STREET.eq(street))
}
If this is allowed is the default condition 'AND' between the different filters?
If the default is 'AND' how do we achieve the use case of 'OR'

The default behavior is an 'AND' connection between all given FilterExpression.
To make this more explicit as well as allowing an 'OR' connection you might consider building the FilterExpression "externally", e.g. like this:
import io.vavr.collection.List;
...
List<ExpressionFluentHelper<YOUR_ENTITY>> expressions = List.empty();
if (zipCode != null) {
expressions = expressions.append(Address.ZIPCODE.eq(zipCode););
}
if (street != null) {
expressions = expressions.append(Address.STREET.eq(street));
}
AddressFluentHelper queryHelper = service.getAllAddress();
if (!expressions.isEmpty()) {
// this combines all elements in the "expressions" via "or", starting from the left/the first entry
ExpressionFluentHelper<YOUR_ENTITY> combinedExpression = expressions.reduceLeft(ExpressionFluentHelper::or);
queryHelper.filter(combinedExpression);
}

Related

Combine Search and checkbox filters in Vue js

I have to filter a list using a Search input field and als some Checkboxes (filter on a category).
I have both functionalities working independently.
The Search field
computed: {
getfilteredData() {
return this.experiences.filter(experience =>
experience.name.toLowerCase().includes(this.search.toLowerCase()) ||
experience.category.toLowerCase().includes(this.search.toLowerCase()
)
)
}
},
The Checkboxes
computed: {
getfilteredData() {
if (!this.checkedCategories.length)
return this.experiences
return this.experiences.filter(experience =>
this.checkedCategories.includes(experience.category))
}
},
How do I combine those filters? So they are working simultaneously?
combining both filters in succession will filter both as an AND statement
getfilteredData() {
return this.experiences.filter(experience =>
experience.name.toLowerCase().includes(this.search.toLowerCase()) ||
experience.category.toLowerCase().includes(this.search.toLowerCase()
)
).filter(experience =>
// if there are no checkboxes checked. all values will pass otherwise the category must be included
!this.checkedCategories.length || this.checkedCategories.includes(experience.category)
)
}
otherwise, you could combine them in one filter with (firstCondition || secondCondition) with the same logic you use above.
I saw your other question that got closed Write my Javascript more cleaner in my Vue js search functionality
where I think you could rewrite your function like this
experience => {
let reg = new RegExp(this.search, 'gi')
return reg.test(`${experience.name} ${experience.category}`)
}
using g means that your string can be in any position, but you must reconstruct your regex on each test otherwise you can end up with issues found here
Why am I seeing inconsistent JavaScript logic behavior looping with an alert() vs. without it?
using i means it will ignore casing so you don't need to worry about using toLowerCase()
thus your filter can be written like this in one statement
experience => {
let reg = new RegExp(this.search, 'gi')
// search input matches AND the checkbox matches
return reg.test(`${experience.name} ${experience.category}`) && (!this.checkedCategories.length || this.checkedCategories.includes(experience.category))
// search input matches OR the checkbox matches
//return reg.test(`${experience.name} ${experience.category}`) || (!this.checkedCategories.length || this.checkedCategories.includes(experience.category))
}

NHibernate queryover how to apply date isbetween without including the from and todate

I am trying to write NHibernate queryover to select all records which has been deleted between two dates. I am using IsBetween().And(). But how do i write if i dont want to include both the fromdate and todate?
Here is my query:
public IEnumerable<DeletedRecord> Search(
DateTime deletedFrom,
DateTime deletedTo
)
{
DeletedRecord delAlias = null;
var query = Session.QueryOver(() => delAlias);
query.Where(() => delAlias.DeletedDate.IsBetween(deletedFrom).And(deletedTo));
return query.Future<DeletedRecord>();
}
Can anyone help me how to achieve so that i can bring all records after the deletedFrom date and before the deletedTo date?
Thanks
Just construct your date in 2 steps:
var query = Session.QueryOver(() => delAlias);
if(youNeedFromDate) //first step
query = query.Where(() => delAlias.DeletedDate >= deletedFrom);
if(youNeedToDate) //second step
query = query.Where(() => delAlias.DeletedDate <= deletedTo);
youNeedFromDate and youNeedToDate are bool variables that you can pass to your function or it could be different condition upon your logic.
Such cases happen quite often . defining extension method helps a lot. see below
public static IQueryOver<T, T> WhereIf<T>(this IQueryOver<T, T> query,bool condition, Expression<Func<T, bool>> expression) where T : class
{
if (condition)
{
query = query.And(expression);
}
return query;
}
Using the above you can chain you conditions and only it will only include the where condition if the first arg evaluates to true.
var query= Session.QueryOver<DeletedRecord>()
.WhereIf(filterByFrom,d=>d.DeletedDate>=fromDate)
.WhereIf(filterByTo,d=>d.DeletedDate<=toDate);

Knockout Binding with Multiple If statements

I am applying binding on a style and have succeeded in making the background colour change based on two scenarios. At present it says if the status is 'START', make the background #d10000, else make the background #93d667.
style: { background: ManagerStatus() == 'START' ? '#d10000' : '#93d667' }
I would like the following functionality:
If START, make #d10000
else if CONTINUE, make #93d667
else make #f7f7f7
How do I achieve these multiple case statements in Knockout binding?
Regards
Alexandra
Thanks guys. For future reference someone showed me that you can actually have multiple cases in the data-bind attribute:
{background: ManagerStatus() == 'START' ? '#d100000' : (ManagerStatus() == 'CONTINUE' ? '#93d667' : '#f7f7f7')}
Alexandra
You avoid filling your html with conditional logic and create a knockout computed observable in your viewmodel like so:
// or however your viewModel is currently set up.
var viewModel = {
ManagerStatus: ko.observable()
}
viewModel.statusBackground = ko.computed(function() {
status = this.ManagerStatus(),
switch (status) {
case "START": return "#d10000";
case "CONTINUE": return "#93d667";
default: return #f7f7f7;
}
}, viewModel);
html
style: { background: statusBackground }
You could do it by nesting two ternary operator expressions. But doing so it's not a good idea: it's much better to modify your View Model, and include a computed observable that returns the backgraound color. Something like this:
var vm = function() {
var self = this;
self.ManagerStatus = ko.observable();
self.backgroundcolor = ko.computed(function() {
ManagerStatus() == 'START'
? '#d10000' : ManagerStatus() == 'CONTINUE'
? '#93d667' : '#f7f7f7';
});
return self;
};
The binding would be like this:
style: { background: backgroundcolor }
Note that you in this case can use a pure computed, instead of a regular computed.
NOTE: I've shown how to write a nested ternary operator, and you could include it in the binding expression. But, if it looks ugly in a view model definition, it's even more ugly in a binding expression. In fact, I wouldn't write it like this in the view model definition. Much better to use chained if else or switch to make it more readable.

How to use if let with another statement in swift?

If want to both assign a string and check that its not empty in Swift.
if let alternative3Text = attributes.stringForKey("choiceThree") && alternative3Text != "" {
// do stuff with alternative3Text
}
Is this possible in Swift, or do i have to do a nested if-statement?
Update: As of Swift 3 (Xcode 8), additional clauses are
separated by a comma, not by where:
if let alternative3Text = attributes.string(forKey: "choiceThree"),
alternative3Text != "" {
// do stuff with alternative3Text
}
Update: As of Swift 1.2 (Xcode 6.3 beta), you can combine
optional binding with additional conditions:
if let alternative3Text = attributes.stringForKey("choiceThree") where alternative3Text != "" {
// do stuff with alternative3Text
}
Using switch-case still works but is not necessary anymore for this purpose.
Old answer:
It is not possible with an if statement, but with switch.
A switch case can use a where clause to check for additional conditions
(documentation).
Assuming (from your question) that attributes.stringForKey("choiceThree") returns
String?, the following would work:
switch (attributes.stringForKey("choiceThree")) {
case .Some(let alternative3Text) where alternative3Text != "":
// alternative3Text is the unwrapped String here
default:
break
}
No, you can't require additional expressions to be true in an if let statement. You will need to add additional code to do this in either the form of a nested if statement as you've already mentioned, or in some other way. If your only requirement is to keep this statement looking clean and wouldn't mind moving some of the logic elsewhere, you could always make an extension to what ever type your attributes variable is to add this functionality.
Here's an example if attributes was an instance of NSUserDefaults. (just because it already contains a stringForKey() instance method.)
extension NSUserDefaults {
func nonEmptyStringForKey(key: String) -> String? {
let full = self.stringForKey(key)
return full != "" ? full : nil
}
}
And then use it like this
if let alternative3Text = attributes.nonEmptyStringForKey("choiceThree") {
// stuff
}

How i can get latest record by using FirstOrDefault() method

Suppose i have 2 records in data base
1) 2007-12-10 10:35:31.000
2) 2008-12-10 10:35:31.000
FirstOrDefault() method will give me the first record match in sequence like 2007-12-10 10:35:31.000 but i need the latest one which is 2008-12-10 10:35:31.000
if ((from value in _names where value != null select value.ExpiryDate < now).Any())
{
return _names.FirstOrDefault();
}
You can use:
return _names.LastOrDefault();
However, your if just sends another unnecessary query (and it is a wrong query too). If you don't have any record, LastOrDefault and FirstOrDefault will return null. You can use something like this to improve the code:
var name = _names.LastOrDefault();
if(name != null)
{
return name;
}
// other code here
If you really want to use FirstOrDefault, you should order descending, like:
var name = _names.Where(n => n.ExpiryDate < now).OrderByDescending(n => n.ExpiryDate).FirstOrDefault();

Resources