Question

Let's consider the following classes:

 public abstract class BaseEntity 
 {
    public virtual Guid Id { get; set; }
 }

 public abstract class Resource : BaseEntity
 {
    public virtual EResourceType ResourceType { get; set; }
 }

 public class PhysicalFile : Resource
 {      
    public virtual string FileName { get; set; }
 }

 public  class Url : Resource
 { 
 }

 public class SourceMaterial : BaseEntity
 {     
    public virtual Guid? ResourceId { get; set; }
    public virtual Resource Resource { get; set; }
 }

When I query for a SourceMaterial entity, the correct resource entity is created (a PhysicalFile entity or a Url entity, according to the ResourceType.

However if I do this:

var query = entityQuery.from('Requests')
var predicate = new breeze.Predicate('sourceMaterials', 'any', new breeze.Predicate('resource.fileName', 'eq', '.doc'));

(code is truncated for clarity)

then when I execute the query I get the error:

Error: unable to locate property: fileName on entityType: Resource:#CdT.EAI.Business.Entities undefined 

That makes sense because the fileName property only exists on the PhysicalFile entity, but does this mean I cannot build such query ?

Was it helpful?

Solution

Breeze does not support this syntax, i.e. restricting a base class based on a subclasses criteria. ( Not sure how it could even be translated into a server query without some additional information).

Providing i'm understanding your schema correctly, I think that your best approach will be to use Breeze's 'withParameters' method in combination with another service endpoint where you handle the subtype manipulation. i.e. something like

[HttpGet]
public IQueryable<Request> RequestsForFilesEndingWith(string fileExtn) {
  var requests = ContextProvider.Context.Requests
      .Where(r => r.SourceMaterials.OfType<PhysicalFile>
         .Any( pf => pf.FileName.EndsWith(fileExtn));
}

And your client query becomes:

 var query = entityQuery.from('RequestsForFilesEndingWith')
   .withParameters({ fileExtn: ".doc" });

Otherwise, the closest you will be able to get is to accomplish at least partial filtering by restricting on the 'resourceType' property ( which is on the base class) instead of the 'fileName' property

var query = entityQuery.from('Requests')
var predicate = new breeze.Predicate('sourceMaterials', 'any', new breeze.Predicate('sourceMaterial.resourceType', 'eq', ???fileNameResourceType???));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top