像这样使用扩展方法怎么样:
public static T FirstOrCreate<T>(this IEnumerable<T> source) where T : class, new()
{
var result = source.FirstOrDefault();
return result != null ? result : new T();
}
如果你希望它能接受一个谓词,你可以使用这个定义:
public static T FirstOrCreate<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate) where T : class, new()
{
var result = source.FirstOrDefault(predicate);
return result != null ? result : new T();
}
这样你就可以将它用作FirstOrDefault()的替代了:
Invoice selectedInvoice = (from i in Invoices
where i.ID == invoiceID
select i).FirstOrCreate();
或者使用 Predicate:
Invoice selectedInvoice = db.Invoices.FirstOrCreate(i => i.ID == invoiceID);
将返回匹配的实体或新的(非空)实体。
编辑:我今天一直在思考这个问题,我发现上述方法需要您检测实体是否是新的(不存在的),并将其附加到 DataContext 上,因此我想出了这个妥协方案,使用相同的方法:
public static T FirstOrCreate<T>(this IEnumerable<T> source, DataClassesDataContext db) where T : class, new()
{
var result = source.FirstOrDefault();
if (result == null)
{
result = new T();
db.GetTable<T>().InsertOnSubmit(result);
}
return result;
}
缺点是您必须将DataContext作为参数传递,但它应该足够好用:
Customer selectedCustomer = (from c in db.Customers
where c.CustomerId == selectedCustomerId
select c).FirstOrCreate(db);
肯定有人会点个赞吧?:)