参考下面的两个类,我经常写这样的LINQ语句..
using (var db = new DBContext())
{
var result = db.Countries
.Select(c => new
{
c.Name,
c.Leader != null ? c.Leader.Title : String.Empty,
c.Leader != null ? c.Leader.Firstname : String.Empty,
c.Leader != null ? c.Leader.Lastname : String.Empty
});
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public Leader Leader { get; set; }
}
public class Leader
{
public string Title { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
}
我的问题是我不得不经常重复我对子导航属性的空检查,我想知道是否有一种方法可以使用某种表达式树动态提取属性值,同时检查空值,如果他们没有存在发回一个空字符串,类似于下面的方法..
public class Country
{
// Properties //
public string SafeGet(Expression<Func<Country, string>> fnc)
{
// Unpack fnc and check for null on each property?????
}
}
用法:
using (var db = new DBContext())
{
var result = db.Countries
.Select(c => new
{
c.Name,
c.SafeGet(l => l.Leader.Title),
c.SafeGet(l => l.Leader.Firstname),
c.SafeGet(l => l.Leader.Lastname)
});
}
如果有人可以提供一个很棒的基本示例,因为除了创建表达树之外,我还没有很多经验。
感谢。
更新 - &gt;会有类似下面的工作吗?
public string GetSafe(Expression<Func<Country, string>> fnc)
{
var result = fnc.Compile().Invoke(this);
return result ?? string.Empty;
}
答案 0 :(得分:1)
我认为没有必要表达。我只想找一个类似
的扩展方法 public static class ModelExtensions
{
// special case for string, because default(string) != string.empty
public static string SafeGet<T>(this T obj, Func<T, string> selector)
{
try {
return selector(obj) ?? string.Empty;
}
catch(Exception){
return string.Empty;
}
}
}
它适用于所有类,您可以进一步实现其他数据类型。用法与你的相同。
答案 1 :(得分:0)
我认为你想要这样的东西:
public static class ModelExtensions
{
public static TResult SafeGet<TSource, TResult>(this TSource obj, System.Func<TSource, TResult> selector) where TResult : class
{
try
{
return selector(obj) ?? default(TResult);
}
catch(System.NullReferenceException e)
{
return default(TResult);
}
}
}