IQueryable<Organization> query = context.Organizations;
Func<Reservation, bool> predicate = r => !r.IsDeleted;
query.Select(o => new {
Reservations = o.Reservations.Where(predicate)
}).ToList();
此查询抛出“内部.NET Framework数据提供错误1025”异常,但下面的查询没有。
query.Select(o => new {
Reservations = o.Reservations.Where( r => !r.IsDeleted)
}).ToList();
我需要使用的第一个,因为我需要if语句来检查一些构建正确的谓语。 我知道,我不能在这种情况下,这就是为什么我传递一个委托作为参数,如果语句使用。
我怎样才能让第一次查询的工作?
虽然上述回答是真实的,请注意,尝试一个select语句必须调用后使用它时, AsQueryable()
明确,否则编译器会认为我们尝试使用IEnumerable的方法,它期待Func
,而不是Expression<Func>
。
这可能是楼主的问题,否则编译器会抱怨最多的,它正在寻找的时间Expression<Func>
而不是Func
。
演示:下面将失败:
MyContext.MySet.Where(m =>
m.SubCollection.Select(s => s.SubItem).Any(expr))
.Load()
虽然下面的工作:
MyContext.MySet.Where(m =>
m.SubCollection.Select(s => s.SubItem).AsQueryable().Any(expr))
.Load()
创建赏金(老鼠!) 之后 ,我发现这个答案 ,解决我的问题。 (我的问题涉及到.Any()
调用,这是一个小比这个问题更复杂......)
总之,这里是你的答案:
IQueryable<Organization> query = context.Organizations;
Expression<Func<Reservation, bool>> expr = r => !r.IsDeleted;
query.Select(o => new { Reservations = o.Reservations.Where(expr) })
.ToList();
阅读参考答案的,为什么你需要的局部变量的解释expr
,你不能直接引用返回类型的另一种方法Expression<Func<Reservation, bool>>
。
感谢执行ping我。 我想我是在正确的轨道上毕竟。
总之,再次重申, LINQ到实体 (感谢乔恩斯基特指正当我在我自己的思维过程在评论混淆)上运行表达式树 ; 它允许投影翻译lambda表达式由到SQL QueryProvider
。
经常Func<>
行之有效的LINQ到对象。
所以在这种情况下,当你使用实体框架,传递给EF的任何断言IQueryable
有可能成为Expression<Func<>>
。
我只是在不同的场景中遇到此问题。
我有一个静态类富有Expression
谓词,我可以再组合或传递到EF查询。 其中之一是:
public static Expression<Func<ClientEvent, bool>> ClientHasAttendeeStatus(
IEnumerable<EventEnums.AttendeeStatus> statuses)
{
return ce => ce.Event.AttendeeStatuses
.Where(a => a.ClientId == ce.Client.Id)
.Select(a => a.Status.Value)
.Any(statuses.Contains);
}
这是抛出1025错误由于Contains
方法群呼。 实体框架预期的表达 ,发现一个方法组 ,这导致错误。 转换的代码使用lambda(其可被隐式转换为表达式)固定在所述误差
public static Expression<Func<ClientEvent, bool>> ClientHasAttendeeStatus(
IEnumerable<EventEnums.AttendeeStatus> statuses)
{
return ce => ce.Event.AttendeeStatuses
.Where(a => a.ClientId == ce.Client.Id)
.Select(a => a.Status.Value)
.Any(x => statuses.Contains(x));
}
除了:我然后简化表达式ce => ce.Event.AttendeeStatuses.Any(a => a.ClientId == ce.Client.Id && statuses.Contains(a.Status.Value));
也有类似的问题。 的ViewModels看起来像这样的库:
public class TagViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public static Expression<Func<SiteTag, TagViewModel>> Select = t => new TagViewModel
{
Id = t.Id,
Name = t.Name,
};
这工作:
var tags = await db.Tags.Take(10).Select(TagViewModel.Select)
.ToArrayAsync();
但是,这不会编译:
var post = await db.Posts.Take(10)
.Select(p => new {
Post = p,
Tags = p.Tags.Select(pt => pt.Tag).Select(TagViewModel.Select)
})
.ToArrayAsync();
由于第二.Select
是乱的-第一个实际上是所谓的关闭一个ICollection的,这是不IQueryable的,所以它消耗该第一表达为纯Func
,不Expression<Func...
。 返回IEnumerable<...
,因为此页面上进行讨论。 所以.AsQueryable()
救援:
var post = await db.Posts.Take(10)
.Select(p => new {
Post = p,
Tags = p.Tags.Select(pt => pt.Tag).AsQueryable()
.Select(TagViewModel.Select)
})
.ToArrayAsync();
但是,创建一个新的,怪异的问题:无论是我得到的内部框架...错误1025,或我得到一个满载后的变量.Post
财产,但.Tags
酒店,这似乎是用于一个EF代理对象延迟加载。
解决的办法是控制标签的返回类型,通过结束使用匿名类:
public class PostViewModel
{
public Post Post { get; set; }
public IEnumerable<TagViewModel> Tags { get; set; }
现在选择这个而这一切的工作原理:
var post = await db.Posts.Take(10)
.Select(p => new PostViewModel {
Post = p,
Tags = p.Tags.Select(pt => pt.Tag).AsQueryable()
.Select(TagViewModel.Select)
})
.ToArrayAsync();