Breeze can query for condition1 AND condition2 by using multiple where statements. But can it query for condition1 OR condition2?
If not, what is the recommended way of achieving the same effect when using Breeze?
I am currently thinking the only way to do this is to perform the query on the server with a special action method, which creates some problems.
Use the Predicate like this sample:
var p1 = new breeze.Predicate("IsArchived", "==", false);
var p2 = breeze.Predicate("IsDone", "==", false);
var predicate = p1.and(p2);
var query = new EntityQuery("Todos").where(predicate);
Documentation is available here:
http://www.breezejs.com/documentation/query-filter
OK, the problem is the Breeze API and Docs are a little lacking with some typos.
The answer is to use the 'or' method of the Predicate class to create a new Predicate object that is passed to the where method.
Given 3 predicates you 'or' them together like so:
var newPred = p1.or(p2, p3);
or
var preds = [p2, p3];
var newPred = p1.or(preds);
or fluent method:
var p4 = Predicate.create("ShipCity", "startswith", "F")
.or("Size", "gt", 2000);
or using the static 'or' method
var newPred = Predicate.or(p1, p2, p3);
Related
How can I query in breeze a contains query of list if integers?
kind of this?
elemnts.where(p => listofids.contains(p.id));
For now you need to use 'or' clauses
var whereClause = breeze.Predicate.create("id", "==", 3)
.or("id", "==", 5)
.or("id", "==", 6);
var query = breeze.EntityQuery.from("elemnts").where(whereClause);
or ( with your list of ids):
var preds = listOfIds.map(function(id) {
return breeze.Predicate.create("id", "==", id);
})
var whereClause = Predicate.or(preds);
var query = breeze.EntityQuery.from("elemnts").where(whereClause);
I'm trying to configure the proper syntax for breeze.js when mixing AND and OR predicates. I did not see an example on the breeze site and could not find one anywhere else.
Basically I want to do something like this in my WHERE clause:
(
age > 30 AND
sex == 'M' AND
jobStartDate >= '1/1/2000'
)
OR
(
exemptStatus == 1
)
this will bring back entities that match the 3 criteria OR are exempt. I'm using EF6 with ODATA syntax.
Thanks
Try this:
var Predicate = breeze.Predicate;
var baseQuery = EntityQuery.from("Something");
var pred1 = new Predicate("age", ">", 30);
var pred2 = new Predicate("sex", "==", 'M');
var pred3 = new Predicate("jobStartDate", ">=", new Date(2000,1,1));
var pred4 = new Predicate("exemptStatus", "==", 1);
var compositePred = pred1.and(pred2).and(pred3).or(pred4);
var query = baseQuery.where(compositePredicate);
myEntityManager.executeQuery(query);
or
var compositePred = Predicate.and(pred1, pred2, pred3).or(pred4);
I want to write a slightly complex query, so I wonder if there is a way to provide a custom function as the predicate of a where clause.
For example, it would be nice if we could do something like:
var myArray = [1, 2, 3];
var filter = function (person) {
return elementExists(person.id, myArray);
};
EntityQuery.from('persons').toType('Person')
.where(filter);
Looking at the source code I realized that such capability is not present in the latest version of BreezeJS (i might be wrong).
I just wonder if breeze supports anything similar to that.
On the client side you should be able to find out if the element exists by checking the length of the return.
var getItems = function (runId, tankId, topicId) {
var localquery = EntityQuery.from("Items")
.using(manager);
var p1 = new breeze.Predicate("runId", "eq", runId);
var p2 = breeze.Predicate("tankId", "eq", window.app.vm.tanks.activetank());
var p3 = breeze.Predicate("topicId", "eq", topicId);
var p4 = breeze.Predicate("topicId", "eq", app.Topics.Growth_Topic);
var pred;
var runId = p1._value;
var tankId = p2._value;
// If the third parameter exists, add it to your complex predicate
// adding a specific Topic to the predicate
// Otherwise only add the General topic
if (p4)
pred = breeze.Predicate.or([p3, p4]);
else
pred = breeze.Predicate.or(p3);
var newpred = breeze.Predicate.and([p1, p2, pred]);
// newpred is now querying for a specific runId and tankId and (p3 or p4) if p4 exists
// otherwise it is querying for runId and tankId or (p3)
// So look in the local metadataStore first
var queryb = localquery.where(newpred);
var results = manager.executeQueryLocally(queryb);
// If we do have it locally use it
if (results.length) {
window.app.vm.Items.Items(results);
}
// otherwise get it from the database
else {
var query = EntityQuery
.from("Items")
.where(newpred);
// return the promise from breeze
return manager.executeQuery(query)
.then(function (data) {
// check to see if the call to the webapi controller returned any data
if (data.length > 0) {
// stick it into the viewmodel it to your viewmodel
window.app.vm.Items.Items(data.results);
return "element exists";
} else {
return "element does not exist";
}
})
.fail(queryFailed);
}
};
This example is quite a bit more complicated that you requested, so cut out the parts you do not want to simplify your query. I am showing you here how to get both an "and" and an "or" into your query. I am also showing how to check the local metadataStore, to see if the item is there before going to the server.
If the item does not exist and you want to create it, be careful about your thread timing and wrap the object creation in a promise before you do something like navigating to another page to show the new item. The navigation may be faster than the creation function and the new item may not be bound into your viewmodel yet by knockout, so it might show up blank on the new page. That will drive you crazy for quite a while.
I have following two Queries on Same Table and need to merge it.
var Prod = this.UnitOfWork.myRepository.GetData();
var PreProd = this.UnitOfWork.myRepository.GetData();
var Merge = Prod.Union(PreProd);
But when i check results of Merge it doesn't show Union but shows following message
Message: This method supports the LINQ to Query Result Union not
working Entities infrastructure and is not intended to be used
directly from your code
How this can be accomplished.
You can use .AsEnumerable() to convert IQueryable to IEnumerable firstly.
var Prod = this.UnitOfWork.myRepository.GetData().AsEnumerable();
var PreProd = this.UnitOfWork.myRepository.GetData().AsEnumerable();
var Merge = Prod.Union(PreProd);
LINQ to EF supported Union:
IQueryable<TSource> Union<TSource>(
this IQueryable<TSource> source1,
IEnumerable<TSource> source2
)
so try:
var Prod = this.UnitOfWork.myRepository.GetData();
var PreProd = this.UnitOfWork.myRepository.GetData();
var Merge = Prod.Union(PreProd.AsEnumerable());
I have code like:
var entityX = this._xService.GetAll();
var entityY = this._yService.GetAll();
Both are returned as IEnumerable types. I need to inner join the two into a something like a JoinedList class that has to be IQueryable.
I'm looking for ways to do this please using LINQ.
Many Thanks
LINQ to Objects is excellent glue:
var entityX = this._xService.GetAll();
var entityY = this._yService.GetAll();
var joinedSequence = from x in entityX
join y in entityY on x.Key equals y.Key
select new { x, y };
var joinedQueryable = joinedSequence.AsQueryable();
You shouldn't really need that last step; IQueryable<T> is unnecessary because LINQ to Objects works just fine with IEnumerable<T>.