Weej
Weej

Reputation: 1022

Breeze work-around for multi valued property queries

I'm trying to assemble ad-hoc queries to Breeze.

I have a physician.contact.addresses relationship.

When I try:

myPred =  new pred('contact.addresses.street1', op.StartsWith, "a");

And execute it I get:

"The parent value for a property access of a property 'Addresses' is not a single value. Property access can only be applied to a single value."

To try a work-around I've tried parsing out those many-relationships and am passing it to the breeze controller in .withParameters like this:

var criteriaStr = toManyArray.length ? ko.utils.stringifyJson(toManyArray) : "";
query = query.withParameters({ searchParms: criteriaStr });

where toManyArray is an array of fieldName:value pairs.

on the controller side:

[HttpGet]
public IQueryable<Physician> Physician(string searchParms = null)
{
  if (searchParms != null)
  {
    var ser = new JavaScriptSerializer();
    var searchCritAry = ser.Deserialize<String[]>(searchParms);

    foreach (var aryItem in searchCritAry)
    {
      // aryItem looks like this:
      // f_str_street_from_addresses:a
      var predEnt = aryItem.Split(':')[0].Split('_')[4];
      var predField = aryItem.Split(':')[0].Split('_')[2];    
      var predVal = aryItem.Split(':')[1];

      switch (predEnt)
      {
        case "addresses":
          switch (predField)
          {
            case "street":
              //physPool = 
                _contextProvider.Context.Physicians
                .Where(p => p.Contact.Addresses.Any(a => a.Street1.StartsWith(predVal)));
              break;
            case "street2":
             //physPool =  
               _contextProvider.Context.Physicians
                .Where(p => p.Contact.Addresses.Any(a => a.Street2.StartsWith(predVal)));
              break;
          }
          break;
      }
    }
    // here I want to combine the .Where clauses from above with the breeze preds
    return _contextProvider.Context.Physicians;
  }
  return _contextProvider.Context.Physicians;
}

It's not working and only returning a selection using the predicates that are passed in the normal way through Breeze's query. I don't see how to pass the filtered IQueryable to Breeze's _contextProvider.

Thanks for any suggestions.

Upvotes: 1

Views: 1145

Answers (1)

Jay Traband
Jay Traband

Reputation: 17052

Take a look at the new "any/all" support in Breeze ( as of version 1.4.7). Some examples may be found here: http://www.breezejs.com/documentation/query-examples

You can construct your query/predicate like this:

var pred = new Breeze.Predicate('contact.addresses', "any", 'street1', op.StartsWith, "a"); 
var query = EntityQuery.from("Physicians").where(pred);

or simply

var query = EntityQuery.from("Physicians")
       .where("contact.addresses", "any", "street1", "startsWith", 'a')

You may want to add an expand if you want the contact and address information sent down as well.

query = query.expand("contact.addresses");

If you have a need for nested any/all expressions you may need to add the following configuration to your BreezeController to determine just how deep you want to allow the expressions to go (2 in the example below):

[BreezeController(MaxAnyAllExpressionDepth = 2)]

Upvotes: 1

Related Questions