EF-Linq 将实体对象转换为搜索条件以进行通用动态查询

2 篇文章 0 订阅

网上找了很久都没找到想要的代码,于是自己写了一份,以作分享。

思路是根据传递进来的对象通过反射来获取对应的属性及属性值,然后再进行比较,接着返回Func对象。

方法主体:

        /// <summary>
        /// 根据传递的对象生成Func表达式,作为Linq的Where参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public static Func<T, bool> GetFunc<T>(T obj)
        {
            if (obj == null) return null;
            Func<T, bool> func = item =>
            {
                Type t = typeof(T);
                foreach (var prop in t.GetProperties())
                {
                    if (!PropIsEquals(prop.PropertyType, prop.GetValue(item), prop.GetValue(obj)))//此处判断item是否符合搜索条件
                    {
                        return false;
                    }
                }
                return true;
            };
            return func;
        }

<span style="white-space:pre">	</span>/// <summary>
        /// 根据属性类型及属性值进行比较
        /// </summary>
        /// <param name="_type">属性类型</param>
        /// <param name="val1">待比较的值</param>
        /// <param name="val2">比较值</param>
        /// <returns></returns>
        public static bool PropIsEquals(Type _type, object val1, object val2)
        {
            if (val1 == null) return true;//如果属性值为空,则不进行比较,返回true

            if (val2 != null && val1 == null) return false;//如果比较值不为Null但是待比较的值为Null,则肯定不相等,返回false

            if (val2 == null && val1 != null) return true;

            //String
            if (_type == typeof(String))
            {
                if (val2.ToString() == String.Empty) return true;//视为空,不比较
                return val1.ToString().Contains(val2.ToString());//like查询,可改成Equals
            }
            else if (_type == typeof(Nullable<DateTime>))
            {
                return val1.ToString().Contains(val1.ToString());
            }

            //Int32
            if (_type == typeof(Int32))
            {
                if (Convert.ToInt32(val2) == 0) return true;//视为空,不比较
                return Convert.ToInt32(val1) == Convert.ToInt32(val2);
            }
            else if (_type == typeof(Nullable<Int32>))
            {
                return Convert.ToInt32(val1) == Convert.ToInt32(val2);
            }

            //DateTime
            if (_type == typeof(DateTime))
            {
                if (Convert.ToDateTime(val2) == DateTime.MinValue) return true;//视为空,不比较
                return Convert.ToDateTime(val1) == Convert.ToDateTime(val2);
            }
            else if (_type == typeof(Nullable<DateTime>))
            {
                return Convert.ToDateTime(val1) == Convert.ToDateTime(val2);
            }

            //Boolean
            if (_type == typeof(Boolean))
            {
                if (Convert.ToBoolean(val2) == false) return true;//视为空,不比较
                return Convert.ToBoolean(val1) == Convert.ToBoolean(val2);
            }
            else if (_type == typeof(Nullable<DateTime>))
            {
                return Convert.ToBoolean(val1) == Convert.ToBoolean(val2);
            }

            //Boolean
            if (_type == typeof(Guid))
            {
                if (Guid.Parse(val2.ToString()) == Guid.Empty) return true;//视为空,不比较
                return Guid.Parse(val1.ToString()) == Guid.Parse(val2.ToString());
            }
            else if (_type == typeof(Nullable<Guid>))
            {
                return Guid.Parse(val1.ToString()) == Guid.Parse(val2.ToString());
            }

            return true;
        }
OK,以上就是全部代码,调用示例:

        var data = from item in (new VocationalEducationEntities().UserInfo) select item;//获取数据源
        var condition=new UserInfo(){Name="A",Sex="男"};//查询条件,此处手动构造
        var newData = data.Where(Common.GetFunc<UserInfo>(condition));//获取姓名等于A,性别等于男的用户


相信很多人看完之后就知道这个方法的缺陷:

1,每次查询都会调用反射,效率不够高效,有关反射效率讨论的文章>>点击打开链接

2,没有比较的关系并且不能进行稍稍复杂的判断,如Age>18并且Age<20,这种判断就写不了


总结:此方法有一定的通用性,但实用性还不够,不过简单使用还是可以的!

最后,希望大家看完之后能够提供一些改正的意见,谢谢!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值