LINQKit
LINQKit copied to clipboard
how to do apply LINQ using ExpressionBuilder on NotMapped property
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
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