我正在为IQueryable<Item>
创建一个扩展方法,其中Item
是实体框架的实体。
extended方法返回第一行中的一个或多个属性值,如果未找到任何行或属性值为null,则返回null。
以下是代码:
internal static TResult FirstOrDefault<TResult>(this IQueryable<Item> items,
Expression<Func<Item, TResult?>> selector, TResult defaultValue)
where TResult : struct
{
var ret = items.Select(selector).FirstOrDefault();
if (ret == null || !ret.HasValue)
{
return defaultValue;
}
return ret.Value;
}
internal static TResult FirstOrDefault<TResult>(this IQueryable<Item> items,
Expression<Func<Item, TResult>> selector, TResult defaultValue)
where TResult : class
{
return items.Select(selector).FirstOrDefault() ?? defaultValue;
}
由于属性可能具有值类型值,因此我决定为value-type和reference-type创建两个扩展方法。
但是当我使用这种方法时(见下文),
_dbContext.Items.Where(i => i.Id == '...').FirstOrDefault(i => i.Modified, DateTime.Now)
VS警告
类型'DateTime'必须是引用类型才能在泛型类型或方法'EFExtensions.FirstOrDefault(IQueryable,Expresion&gt;,TResult)'中将其用作参数'TResult'
我知道这意味着VS尝试使用第二个扩展方法编译此方法,而 DateTime 将违反where TResult : class
约束。
如何在不修改方法名称的情况下让VS使用第一个?
或者有没有更好的方法来实现我的目标?
任何答案都将不胜感激。
谢谢:)
答案 0 :(得分:2)
在第一种方法中,Expression
的返回类型是可空的TResult
,所以您需要做的就是返回它。这可以通过演员表来完成:
_dbContext.Items
.Where(i => i.Id == '...')
.FirstOrDefault(i => (DateTime?)i.Modified, DateTime.Now);