2

I'm using DelegateDecompiler with Entity Framework to add computed properties. I'm also using PredicateBuilder to compose expressions for queries.

I'm having a problem getting the computed properties into SQL when using PredicateBuilder.

For Example:

Get Parents whose children's FullName starts with A, where FullName is a computed property

context.Parents.Where(p => p.Children.Any(c => c.Fullname.StartsWith("A"))).Decompile()

Works as desired.

I want to compose the Where Expression using A universal PredicateBuilder like so ...

var predicateParent = PredicateBuilder.True<ParentEntity>();
var predicateChild = PredicateBuilder.True<ChildEntity>();
predicateChild = predicateChild.And(c => c.FullName.StartsWith("A"));
predicateParent = predicateParent.And(x => x.Children.AsQueryable().Any(predicateChild));
var query = db.Parents.Where(predicateParent).Decompile();
List<ParentEntity> parents = query.ToList();

But it throws exception: The specified type member 'FullName' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

How can the predicates be used with computed properties in children collection?

Here are the entity classes.

    public class ParentEntity
    {
        public ParentEntity()
    {
        Children = new List<ChildEntity>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public virtual List<ChildEntity> Children { get; set; }

    [Computed]
    [NotMapped]
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
}

public class ChildEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }

    [Computed]
    [NotMapped]
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }

    public int ParentId { get; set; }
    public virtual ParentEntity Parent { get; set; }
}

public class ParentChildModel: DbContext
{
    public ParentChildModel()
        : base("name=ParentChildModel")
    {
    }

    public virtual DbSet<ParentEntity> Parents { get; set; }
    public virtual DbSet<ChildEntity> Children { get; set; }
}
  • 2
    Looks like `AsQueryable()` and `Decompile()` don't play nice together. Maybe you should give Linqkit's predicate builder a try. (Although in general, I also prefer the one you use). – Gert Arnold Dec 21 '15 at 13:24
  • Thanks for the tip. I tried LinqKit's predicate builder, but it didn't work. However, LinqKit's Expand() extension did help. I added .Expand() to the predicate in this line `var query = db.Parents.Where(predicateParent.Expand()).Decompile();` and it worked. – user1488937 Jan 21 '16 at 18:04

1 Answers1

0

The solution was to add LinqKit's Expand() extension method to the constructed predicate like this.

var query = db.Parents.Where(predicateParent.Expand()).Decompile();

Thanks Gert for LinqKit suggestion, it got me close enough to stumble on the answer.