How to implement method with expression parameter c#

后端 未结 3 1150
轮回少年
轮回少年 2021-02-06 12:29

I want to create a method like this:

var result = database.Search(x=>x.Name, \"Entity Name field value\");
result = database.Search

        
相关标签:
3条回答
  • 2021-02-06 12:32

    do you want types to dynamic

    public ReturnType Read<ReturnType>(string FieldName, object dfVal)
    {
        if (Res.IsDBNull(Res.GetOrdinal(FieldName)))
            return dfVal;
        try {
            return (ReturnType)Res.GetValue(Res.GetOrdinal(FieldName));
        } catch (Exception ex) {
            return dfVal;
        }
    }
    
    0 讨论(0)
  • 2021-02-06 12:36

    You can turn a selector and value into a predicate using Expression.Equal:

    static IQueryable<TSource> Search<TSource, TValue>(
        this IQueryable<TSource> source,
        Expression<Func<TSource,TValue>> selector,
        TValue value)
    {
        var predicate = Expression.Lambda<Func<TSource,bool>>(
            Expression.Equal(
                selector.Body,
                Expression.Constant(value, typeof(TValue))
            ), selector.Parameters);
        return source.Where(predicate);
    }
    

    Then you just need to do something like:

    var result = database.SomeEntities.Search(x => x.SomeProp, "value");
    

    If you want to do it from the database, then that depends on what the database is; for example, with LINQ-to-SQL you could add an additional method:

    static IQueryable<TSource> Search<TSource, TValue>(
        this System.Data.Linq.DataContext database,
        Expression<Func<TSource, TValue>> selector,
        TValue value) where TSource : class
    {
        IQueryable<TSource> source = database.GetTable<TSource>();
        return Search(source, selector, value);
    }
    

    and use:

    var result = database.Search<SomeEntity, string>(x => x.SomeProp, "value");
    

    frankly I think it is clearer to use the database.SomeEntities version, though.

    0 讨论(0)
  • 2021-02-06 12:51

    I can only think of this (with 2 generic arguments)

        public static IEnumerable<TModel> Search<TModel, TValue>(
            Expression<Func<TModel, TValue>> expression,
            TValue value
        )
        {
            return new List<TModel>();
        }
    

    usage

    var result = Search<EntityType, int>(x => x.Id, 1);
    var result2 = Search<EntityType, string>(x => x.Name, "The name");
    

    you can replace TValue with object to avoid the second generic argument, but I would stick with this.

    Btw. this works great in conjunction with this little helper

    public static class ExpressionHelpers
    {
        public static string MemberName<T, V>(this Expression<Func<T, V>> expression)
        {
            var memberExpression = expression.Body as MemberExpression;
            if (memberExpression == null)
                throw new InvalidOperationException("Expression must be a member expression");
    
            return memberExpression.Member.Name;
        }
    }
    

    Now you can get the Name of the Property (Id oder Name) in this example by calling

    var name = expression.MemberName();
    
    0 讨论(0)
提交回复
热议问题