Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to do apply LINQ using ExpressionBuilder on NotMapped property #187

Open
furanzKafka opened this issue Sep 15, 2023 · 1 comment
Open

Comments

@furanzKafka
Copy link

furanzKafka commented Sep 15, 2023

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(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

@TheConstructor
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants