使用实体框架(LINQ to Entities)
以下工作正常。表达式已转换为SQL
var foos = ctx.Foos.Select(f => new {
P1 = ctx.Bars.FirstOrDefault(b => b.SomeProp == "Const1" && f.X1 == b.Y),
P2 = ctx.Bars.FirstOrDefault(b => b.SomeProp == "Const2" && f.X2 == b.Y),
P3 = ctx.Bars.FirstOrDefault(b => b.SomeProp == "Const3" && f.X3 == b.Y),
}
重复表达式b.SomeProp == "..." && f.X* == b.Y
实际上是真实表达式的简化版本,但是如果你可以帮我理解这一点。我也会弄清楚剩下的......
我想写的是这样的。 (首选)
var foos = ctx.Foos.Select(f => new {
P1 = f.GetBar("Const1", f.X1),
P2 = f.GetBar("Const2", f.X2),
P3 = f.GetBar("Const3", f.X3),
}
但我可能也会喜欢
P1 = ctx.Bars.GetByFoo(f.X1, "Const1");
- or -
P1 = ctx.Bars.FirstOrDefault(GetByFoo(f.X1, "Const1"))
- or -
P1 = ctx.Bars.GetByFoo(x => x.X1, "Const1");
基于这个答案https://stackoverflow.com/a/2244917/2968001我到目前为止最接近的是
ctx.Bars.FirstOrDefault(GetByFoo(x => x.Y == f.X1 , "Const1"))
and
private static Expression<Func<Bar, bool>> GetByFoo(Func<Foo, bool> optionSelector, string par1)
{
return b => b.SomeProp == par1 && optionSelector(o);
}
不幸的是,这个
a)仍然很不理想
b)这不起作用:(。它给出了运行时异常:
从范围''引用的'Foo'类型的变量'f',但它不是 定义
表达式必须保持可翻译。检索所有的foos然后为每个foo检索Bar都不行。
答案 0 :(得分:0)
这些方面的内容如何
public static class Extensions
{
public static IQueryable<T> Filter<T>(this DemoContext instance, Expression<Func<T, bool>> predicate = null, string value = null)
where T : class, IMarker
{
return instance
.Set<T>()
.Where(p => p.SomeProp == value)
.Where(predicate);
}
}
应该允许你写一些类似
的东西var inner1 = ctx.Filter<Bar>(value: "Const1");
var inner2 = ctx.Filter<Bar>(value: "Const2");
var inner3 = ctx.Filter<Bar>(value: "Const3");
var query = from foo in ctx.Foos
select new
{
P1 = inner1.FirstOrDefault(p => p.Y == foo.X1),
P2 = inner2.FirstOrDefault(p => p.Y == foo.X2),
P3 = inner3.FirstOrDefault(p => p.Y == foo.X3),
};
其中IMarker
接口只是为了帮助您处理专门的谓词
public class Foo : IEntity
{
public string X1 { get; set; }
public string X2 { get; set; }
public string X3 { get; set; }
}
public class Bar : IMarker
{
public string SomeProp { get; set; }
public string Y { get; set; }
}
public interface IEntity
{
}
public interface IMarker : IEntity
{
string SomeProp { get; set; }
}