Question

My objective is to have a domain model for writing (so no writable entities exposed to client) and queries for reading (i.e. specialized entity model for reading only).

While watching pluralsight trainings related to Breeze I could not find any example of use I need. What was shown is placing queries to entities inside client java script. But I can't really see any reason for doing so apart from 3 cases: 1. Frequent: Paging in response to user click 2. Frequent: Sorting in response to user sort selection 3. Rare: filtering basing on dynamic filter built by end user - rare because these days you'd rather use a single search box to match any column - no one would normally bother clicking to create complex boolean expressions.

These three cases are crying for queryability at client end. Querying with any other set of conditions (e.g. "orders over $100") I consider as business logic and I don't want to put it into java script as I want to keep client as thin and as dumb as possible (do you really want to decide if $100 is net amount or gross amount at client end?). I prefer to use strongly-typed LINQ queries to the entity model at server end for this. And there is the limitation: the controller methods that return IQueryable will not accept arguments. So there is no way to write a parameterized query where the parameter (like "order value threshold") is handled internally by server and only in the way known to server.

The question: is there a Java Script library which would give me this functionality? What I really need is just a fluent Java Script querying API which - like in Breeze - is automatically converted to a Lambda at server end and applied to my IQueryable or even better - that I can myself inject into my LINQ query at server end.

Was it helpful?

Solution

I'm not entirely sure I understand your question but I do think you've missed out on some of Breeze's capabilities.

Breeze will allow you to expose any client side query that will be applied on top of an existing arbitrary IQueryable on the server... and you can also pass in parameters that operate in concert with the merged query. For example:

On the server you can have an endpoint that looks like this:

[HttpGet]
public IQueryable<Employee> EmployeesFilteredByCountryAndBirthdate(DateTime birthDate, string country) {
  return ContextProvider.Context.Employees.Where(emp => emp.BirthDate >= birthDate && emp.Country == country);
}

That can be queried from the client like this:

var q = EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
        .withParameters({ birthDate: "1/1/1960", country: "USA" });

myEntityManager.executeQuery(q).then(function (data) {
  ... process the results.
}

You can even add a further filter the query so that it represents the application of both the server side logic as well as the client side filter. Something like:

var q = EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
        .withParameters({ birthDate: "1/1/1960", country: "USA" })
        .where("lastName", "startsWith", "S");

In general, I like to think of the client side query as simply a way of "further" restricting the data returned by whatever endpoint you have defined on the server. The server query can be a precise and focused as you want either for security or business logic consolidation purposes. The client side query simply allows you to further restrict the payload returned to whatever subset is useful to your use case.

The Breeze DocCode samples in the Breeze zip contain a number of useful examples like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top