我想将IQueryable
作为参数传递给一个函数,然后调用实体框架提供程序执行查询,如下所示:
public ICollection<MyRowType> RunCommand(IQueryable<MyRowType> query)
{
using (var db = new MyDbContext())
{
var result = db.MyRowType
.Include(r => r.RelatedTableA)
.Include(r => r.RelatedTableB)
.Include(r => r.RelatedTableC)
// How do I make the value in `query` run here?
.ToList();
}
}
我基本上将数据库调用包装到此方法以返回所有必需的包含但我不想失去通过IQueryable<MyRowType>
进行自定义查询的灵活性。
以下是我想要实现的一个例子:
public ICollection<MyRowType> SomeOtherMethod(string id, SomeValue value = null, SomeOtherValue otherValue = null)
{
var query = Enumerable.Empty<MyRowType>()
.Where(r => r.Id == di);
if (value != null)
query = query.Where(r => r.PropertyOne == value);
if (otherValue != null)
query = query.Where(r => r.PropertyTwo == otherValue);
return RunCommand(query);
}
回答更新:
我将Yacoub Massad和dasblinkenlight的答案合并到这两种方法中:
public static ICollection<MyRowType> RunCommand(Expression<Func<MyRowType, bool>> condition)
{
return Get(t => t.Where(condition));
}
public static ICollection<MyRowType> RunCommand(Func<IQueryable<MyRowType>, IQueryable<MyRowType>> query)
{
using (var db = new DbContext())
{
var includes = db.MyRowType
.Include(r => r.RelatedTableA)
.Include(r => r.RelatedTableB)
.Include(r => r.RelatedTableC)
var result = query(includes)
.ToList();
return result;
}
}
答案 0 :(得分:1)
您应该通过<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="background">
<div class="newItem">
<p> Add item </p>
</div>
</div>
</body>
代替Func<IQueryable<MyRowType>,IQueryable<MyRowType>>
,如下所示:
IQueryable<MyRowType>
然后你可以像这样使用它:
public ICollection<MyRowType> RunCommand(Func<IQueryable<MyRowType>,IQueryable<MyRowType>> func)
{
using (var db = new MyDbContext())
{
IQueryable<MyRowType> q = db.MyRowType
.Include(r => r.RelatedTableA)
.Include(r => r.RelatedTableB)
.Include(r => r.RelatedTableC);
var result = func(q);
return result.List();
}
}
或者使用其他类似的LINQ方法:
var result = RunCommand(q => q.Where(....));
请注意,您无法传递将选择与var result = RunCommand(q => q.Where(....).OrderBy(x => ...).Take(10));
不同的类型的查询。如果你想要那么你可以使方法通用如下:
MyRowType
现在您可以像这样使用它:
public ICollection<T> RunCommand<T>(Func<IQueryable<MyRowType>,IQueryable<T>> func)
{
using (var db = new MyDbContext())
{
IQueryable<MyRowType> q = db.MyRowType
.Include(r => r.RelatedTableA)
.Include(r => r.RelatedTableB)
.Include(r => r.RelatedTableC);
var result = func(q);
return result.List();
}
}
答案 1 :(得分:1)
从IQueryable<T>
中提取表达式并不容易,并且您无法直接应用传递给方法的queryable
。但是,由于您似乎试图通过在不更改输出类型的情况下传递IQueryable<T>
来限制查询,因此可能更容易将API更改为采用条件而不是IQueryable<T>
,如下所示:< / p>
public ICollection<MyRowType> RunCommand(Expression<Func<MyRowType,bool>> condition) {
using (var db = new MyDbContext()) {
var result = db.MyRowType
.Include(r => r.RelatedTableA)
.Include(r => r.RelatedTableB)
.Include(r => r.RelatedTableC)
.Where(condition)
.ToList();
}
}
如果您使用LINQ to Entities predicate combiner,则可以将自定义条件与RunCommand
方法中执行的常规准备步骤结合使用:
public ICollection<MyRowType> SomeOtherMethod(string id, SomeValue value = null, SomeOtherValue otherValue = null) {
Expression<Func<MyRowType,bool>> condition =
r => r => r.Id == di;
if (value != null)
condition = condition.And(r => r.PropertyOne == value);
if (otherValue != null)
condition = condition.And(r => r.PropertyTwo == otherValue);
return RunCommand(query);
}