LINQKit icon indicating copy to clipboard operation
LINQKit copied to clipboard

how to do apply LINQ using ExpressionBuilder on NotMapped property

Open furanzKafka opened this issue 2 years ago • 1 comments

i have [NotMapped] property in entity, i want to apply filter on this property like this

public class MyEntity : IEntity { public Guid ID { get; set; } public string Code { get; set; } public string Description { get; set; } [NotMapped] public string CodeAndDescription => Code + " / " + Description; }

var pre = ExpressionBuilder.New<MyEntity>(true); if (filter.PublicFilter != null) { string keywords = filter.PublicFilter.ToLower().Replace("İ", "i").Replace("ı", "i");

pre.And(x => x.CodeAndDescription.ToLower().Replace("İ", "i").Replace("ı", "i").Contains(keywords));

}

Of course, a solution can be found in these codes by applying a separate LINQ for Code and a separate LINQ for Description. This solution will not work when there is a more complex situation. But I simply wrote these codes to ask how to apply LINQ to a NotMapped field with expressionbuilder.

how can I do that

furanzKafka avatar Sep 15 '23 12:09 furanzKafka

Hey @furanzKafka,

not sure what ExpressionBuilder is in this context; so I will assume you refer to PredicateBuilder. Your main problem also seems to be EF Core not knowing what a [NotMapped] property is. You can use [Expandable(methodName)] + .Expand() to replace the property by an EF Core mappable expression, though it may not be the optimal expression for your query:

    public class MyEntity
    {
        public Guid ID { get; set; }
        public string Code { get; set; }
        public string Description { get; set; }
        [NotMapped]
        [Expandable(nameof(CodeAndDescriptionExpr))]
        public string CodeAndDescription => Code + " / " + Description;
        private static Expression<Func<MyEntity, string>> CodeAndDescriptionExpr() => e => e.Code + " / " + e.Description;
    }
    
    public class ExpressionBuilderTest {

        [Fact]
        public void ExpressionIsAppliedToMappedProperties()
        {
            var pre = PredicateBuilder.New<MyEntity>(true);
            var keywords = "?";
            pre = pre.And(x => x.CodeAndDescription.ToLower().Replace("İ", "i").Replace("ı", "i").Contains(keywords));
            var fin = pre.Expand();
            Assert.Equal(
                $"x => ((x.Code + \" / \") + x.Description).ToLower().Replace(\"İ\", \"i\").Replace(\"ı\", \"i\").Contains(value({typeof(ExpressionBuilderTest).FullName}+<>c__DisplayClass0_0).keywords)",
                fin.ToString());
        }
    }

If you know, that filter.PublicFilter does not contain / it may be better to search in Code and Description on their own, without concatenating them first.

Hope this gives you some ideas

TheConstructor avatar Oct 07 '23 12:10 TheConstructor