内部.NET Framework数据提供程序错误1025

时间:2012-08-16 15:05:01

标签: c# .net entity-framework entity-framework-4 expression-trees

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语句来构造正确的谓词。我知道在这种情况下我不能使用if语句,这就是我将委托作为参数传递的原因。

如何让第一个查询起作用?

5 个答案:

答案 0 :(得分:35)

虽然上面的答案都是正确的,但请注意,当在select语句之后尝试使用它时,必须显式调用AsQueryable(),否则编译器将假定我们正在尝试使用IEnumerable方法,这些方法期望{ {1}}而非Func

这可能是原始海报的问题,否则编译器会在大多数情况下抱怨它正在寻找Expression<Func>而不是Expression<Func>

演示: 以下内容将失败:

Func

虽然以下方法有效:

MyContext.MySet.Where(m => 
      m.SubCollection.Select(s => s.SubItem).Any(expr))
         .Load()

答案 1 :(得分:25)

创建赏金(老鼠!)之后,我找到了this answer,这解决了我的问题。 (我的问题涉及.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>>的方法。

答案 2 :(得分:19)

感谢你的帮助。我想我毕竟是在正确的轨道上。

无论如何,要重申一下,LINQ to Entities(感谢Jon Skeet在评论中我在自己的思考过程中混淆时纠正了我)Expression Trees;它允许projection to translate the lambda expression to SQL by the QueryProvider

常规Func<>适用于LINQ to Objects.

因此,在这种情况下,当您使用实体框架时,传递给EF的IQueryable的任何谓词都必须是Expression<Func<>>

答案 3 :(得分:5)

我刚刚在不同的场景中遇到过这个问题。

我有一个充满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);
    }

由于Contains方法组调用,这引发了1025错误。实体框架期望 Expression 并找到方法组,这导致了错误。转换代码以使用lambda(可以隐式转换为Expression)修复了错误

    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));

答案 4 :(得分:0)

有类似的问题。 ViewModel库看起来像这样:

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,而不是{{1 }}。返回Expression<Func...,如本页所述。所以IEnumerable<...救援:

.AsQueryable()

但是这会产生一个新的,更奇怪的问题:我得到内部框架...错误1025,或者我得到一个带有满载var post = await db.Posts.Take(10) .Select(p => new { Post = p, Tags = p.Tags.Select(pt => pt.Tag).AsQueryable() .Select(TagViewModel.Select) }) .ToArrayAsync(); 属性的post变量,但是.Post属性有一个似乎用于Lazy-Loading的EF代理对象。

解决方案是通过结束使用Anonymous类来控制Tags的返回类型:

.Tags

现在选择这个,一切正常:

public class PostViewModel
{
    public Post Post { get; set; }
    public IEnumerable<TagViewModel> Tags { get; set; }