我正在使用实体框架来返回我的数据。
我有两个几乎相同的方法/查询。唯一的区别是,有一个额外的Where声明。
第一个查询获取已接受事务的平均值,第二个查询获取所有事务的平均值。
以下是两种方法:
static IEnumerable<BuyerEarning> GetBuyerEPA()
{
var collectTo = DateTime.Now.AddDays(-1).DayEnd();
var collectFrom = collectTo.AddDays(-29).DayStart();
using (var uow = new UnitOfWork(ConnectionString.PaydayLenders))
{
var r = new Repository<MatchHistory>(uow.Context);
return r.Find()
.Where(x =>
x.ResultTypeId == (int)MatchResultType.Accepted &&
x.CreatedOn <= collectTo &&
x.CreatedOn >= collectFrom)
.GroupBy(x => new
{
x.BuyerId,
x.TreeId,
x.TierId
})
.ToList()
.Select(x => new BuyerEarning(
x.Key.BuyerId,
x.Key.TreeId,
x.Key.TierId,
x.Average(y => y.Commission)))
.ToList();
}
}
static IEnumerable<BuyerEarning> GetBuyerEPL()
{
var collectTo = DateTime.Now.AddDays(-1).DayEnd();
var collectFrom = collectTo.AddDays(-29).DayStart();
using (var uow = new UnitOfWork(ConnectionString.PaydayLenders))
{
var r = new Repository<MatchHistory>(uow.Context);
return r.Find()
.Where(x =>
x.CreatedOn <= collectTo &&
x.CreatedOn >= collectFrom)
.GroupBy(x => new
{
x.BuyerId,
x.TreeId,
x.TierId
})
.ToList()
.Select(x => new BuyerEarning(
x.Key.BuyerId,
x.Key.TreeId,
x.Key.TierId,
x.Average(y => y.Commission)))
.ToList();
}
}
我想使用1返回BuyerId,TreeId,TierId,EpaValue,EplValue,而不是2个不同的查询。这是可能的,如果是的话,怎么样?
答案 0 :(得分:3)
您可以使用谓词作为参数创建辅助方法:
static IEnumerable<BuyerEarning> GetXXXX(Func<MatchHistory, bool> predicate = null)
{
var collectTo = DateTime.Now.AddDays(-1).DayEnd();
var collectFrom = collectTo.AddDays(-29).DayStart();
using (var uow = new UnitOfWork(ConnectionString.PaydayLenders))
{
var r = new Repository<MatchHistory>(uow.Context);
var filtered = r.Find()
.Where(x.CreatedOn <= collectTo && x.CreatedOn >= collectFrom);
if(predicate != null)
filtered = filtered.Where(predicate);
return filtered
.GroupBy(x => new
{
x.BuyerId,
x.TreeId,
x.TierId
})
.ToList()
.Select(x => new BuyerEarning(
x.Key.BuyerId,
x.Key.TreeId,
x.Key.TierId,
x.Average(y => y.Commission)))
.ToList();
}
}
然后在每个原始方法中使用它:
static IEnumerable<BuyerEarning> GetBuyerEPA()
{
return GetXXXX(x => x.ResultTypeId == (int)MatchResultType.Accepted);
}
static IEnumerable<BuyerEarning> GetBuyerEPL()
{
return GetXXXX();
}
Btw。 ,为什么在最终投影前使用ToList()
?它使Average
计算由应用程序执行(使用LINQ to Objects),这比SQL Server完成时效率低得多。
答案 1 :(得分:3)
为什么不重构Where
子句并将其作为变量传递?
var epaFilter = new Func<MatchHistory, bool>(x => x.ResultTypeId == (int)MatchResultType.Accepted && x.CreatedOn <= collectTo && x.CreatedOn >= collectFrom);
var eplFilter = new Func<MatchHistory, bool>(x => x.CreatedOn <= collectTo && x.CreatedOn >= collectFrom);
private static IEnumerable<MatchHistory> GetBuyerByFilter(Func<MatchHistory,Boolean> filter)
{
var collectTo = DateTime.Now.AddDays(-1).DayEnd();
var collectFrom = collectTo.AddDays(-29).DayStart();
using (var uow = new UnitOfWork(ConnectionString.PaydayLenders))
{
var r = new Repository<MatchHistory>(uow.Context);
return r.Find()
.Where(filter)
.GroupBy(x => new
{
x.BuyerId,
x.TreeId,
x.TierId
})
.ToList()
.Select(x => new BuyerEarning(
x.Key.BuyerId,
x.Key.TreeId,
x.Key.TierId,
x.Average(y => y.Commission)))
.ToList();
}
}
答案 2 :(得分:3)
虽然大多数其他答案都向您展示了如何使用相同的代码在EPL和EPA之间切换查询,但我相信您所询问的是如何在单个查询中获取这两个值。
static IEnumerable<BuyerEarning> GetBuyerEPA()
{
var collectTo = DateTime.Now.AddDays(-1).DayEnd();
var collectFrom = collectTo.AddDays(-29).DayStart();
using (var uow = new UnitOfWork(ConnectionString.PaydayLenders))
{
var r = new Repository<MatchHistory>(uow.Context);
return r.Find()
.Where(x =>
x.CreatedOn <= collectTo &&
x.CreatedOn >= collectFrom)
.GroupBy(x => new
{
x.BuyerId,
x.TreeId,
x.TierId
})
.Select(x => new BuyerEarning(
x.Key.BuyerId,
x.Key.TreeId,
x.Key.TierId,
x.Average(y => y.Commission), //EPL
x.Where(y => y.ResultTypeId == (int)MatchResultType.Accepted)
.Average(y => y.Commission)) //EPA
.ToList();
}
}
答案 3 :(得分:2)
好像你想要这个:
static IEnumerable<BuyerEarning> GetBuyer(bool acceptedOnly)
{
var collectTo = DateTime.Now.AddDays(-1).DayEnd();
var collectFrom = collectTo.AddDays(-29).DayStart();
using (var uow = new UnitOfWork(ConnectionString.PaydayLenders))
{
var r = new Repository<MatchHistory>(uow.Context);
IQueryable<MatchHistory> results = r.Find()
.Where(x =>
x.CreatedOn <= collectTo &&
x.CreatedOn >= collectFrom);
if (acceptedOnly)
{
results = results
.Where(x => x.ResultTypeId == (int)MatchResultType.Accepted);
}
return results
.GroupBy(x => new
{
x.BuyerId,
x.TreeId,
x.TierId
})
.ToList()
.Select(x => new BuyerEarning(
x.Key.BuyerId,
x.Key.TreeId,
x.Key.TierId,
x.Average(y => y.Commission)))
.ToList();
}
}