您的位置:首页 > 其它

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

2015-12-28 09:38 423 查看
网上找了很久都没找到想要的代码,于是自己写了一份,以作分享。

思路是根据传递进来的对象通过反射来获取对应的属性及属性值,然后再进行比较,接着返回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,这种判断就写不了

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

最后,希望大家看完之后能够提供一些改正的意见,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: