内部。net框架数据提供程序错误1025。

时间:2021-12-05 22:51:03
IQueryable<Organization> query = context.Organizations;

Func<Reservation, bool> predicate = r => !r.IsDeleted;

query.Select(o => new { 
    Reservations = o.Reservations.Where(predicate)
}).ToList();

this query throws "Internal .NET Framework Data Provider error 1025" exception but the query below does not.

这个查询抛出“内部。net Framework Data Provider error 1025”异常,但下面的查询没有。

query.Select(o => new { 
    Reservations = o.Reservations.Where( r => !r.IsDeleted)
}).ToList();

I need to use the first one because I need to check a few if statements for constructing the right predicate. I know that I can not use if statements in this circumstance that is why I pass a delegate as parameter.

我需要使用第一个,因为我需要检查一些if语句来构造正确的谓词。我知道在这种情况下我不能使用if语句,所以我将委托作为参数传递。

How can I make the first query work?

如何进行第一个查询工作?

5 个解决方案

#1


29  

While the above answers are true, note that when trying to use it after a select statement one has to call AsQueryable() explicitly, otherwise the compiler will assume that we are trying to use IEnumerable methods, which expect a Func and not Expression<Func>.

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

This was probably the issue of the original poster, as otherwise the compiler will complain most of the time that it is looking for Expression<Func> and not Func.

这可能是原始海报的问题,否则编译器会抱怨大部分时间都在寻找表达式 而不是Func。

Demo: The following will fail:

演示:以下将失败:

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

While the following will work:

下面的工作将会:

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

#2


24  

After creating the bounty (rats!), I found this answer, which solved my problem. (My problem involved a .Any() call, which is a little more complicated than this question...)

在创造了奖赏(老鼠!)之后,我找到了这个答案,它解决了我的问题。(我的问题涉及a .Any()电话,这比这个问题稍微复杂一点……)

In short, here's your answer:

简而言之,你的答案是:

IQueryable<Organization> query = context.Organizations;

Expression<Func<Reservation, bool>> expr = r => !r.IsDeleted;

query.Select(o => new { Reservations = o.Reservations.Where(expr) })
  .ToList();

Read the referenced answer for an explanation of why you need the local variable expr, and you can't directly reference another method of return type Expression<Func<Reservation, bool>>.

阅读参考答案,解释为什么需要本地变量expr,而不能直接引用另一种返回类型表达式 >。

#3


16  

Thanks for pinging me. I guess I was on the right track after all.

谢谢你联系我。我想我毕竟是在正确的轨道上。

Anyway, to reiterate, LINQ to Entities (thanks to Jon Skeet for correcting me when I got mixed up in my own thought process in the comments) operates on Expression Trees; it allows for a projection to translate the lambda expression to SQL by the QueryProvider.

无论如何,要重申的是,LINQ to实体(感谢Jon Skeet在我在评论中对我的想法进行了混淆)对表达式树进行了操作;它允许投影将lambda表达式转换为QueryProvider。

Regular Func<> works well for LINQ to Objects.

普通的Func<>在LINQ to Objects中很好用。

So in this case, when you're using the Entity Framework, any predicate passed to the EF's IQueryable has to be the Expression<Func<>>.

在这种情况下,当使用实体框架时,传递给EF的任何谓词都必须是表达式 >。

#4


3  

I just experienced this issue in a different scenario.

我只是在不同的情况下经历了这个问题。

I have a static class full of Expression predicates which I can then combine or pass to an EF query. One of them was:

我有一个充满表达式谓词的静态类,我可以将其合并或传递到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);
    }

This was throwing the 1025 error due to the Contains method group call. The entity framework expected an Expression and found a method group, which resulted in the error. Converting the code to use a lambda (which can be implicitly cast to an Expression) fixed the error

这是由于包含方法组调用导致的1025错误。实体框架期望一个表达式并找到一个方法组,结果导致错误。将代码转换为使用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));
    }

Aside: I then simplified the expression to ce => ce.Event.AttendeeStatuses.Any(a => a.ClientId == ce.Client.Id && statuses.Contains(a.Status.Value));

旁白:然后将表达式简化为ce => . event . attendeestatuse。(= >。ClientId = = ce.Client。Id & & statuses.Contains(a.Status.Value));

#5


0  

Had a similar problem. Library of ViewModels that look like this:

有一个类似的问题。像这样的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,
    };

This works:

如此:

var tags = await db.Tags.Take(10).Select(TagViewModel.Select)
    .ToArrayAsync();

But, this won't compile:

但是,这不会编译:

var post = await db.Posts.Take(10)
    .Select(p => new {
        Post = p,
        Tags = p.Tags.Select(pt => pt.Tag).Select(TagViewModel.Select)
    })
    .ToArrayAsync();

Because the second .Select is a mess - the first one is actually called off of an ICollection, which is not IQueryable, so it consumes that first Expression as a plain Func, not Expression<Func.... That returns IEnumerable<..., as discussed on this page. So .AsQueryable() to the rescue:

因为第二个。select是一个混乱,第一个是被取消的ICollection,它不是IQueryable,所以它将第一个表达式作为一个普通的Func,而不是表达式 返回ienumerable>

var post = await db.Posts.Take(10)
    .Select(p => new {
        Post = p,
        Tags = p.Tags.Select(pt => pt.Tag).AsQueryable()
            .Select(TagViewModel.Select)
    })
    .ToArrayAsync();

But that creates a new, weirder problem: Either I get Internal Framework...Error 1025, or I get the post variable with a fully loaded .Post property, but the .Tags property has an EF proxy object that seems to be used for Lazy-Loading.

但这创造了一个新的更奇怪的问题:要么我得到内部框架……错误1025,或者我用一个完全加载的. post属性获得post变量,但是. tags属性有一个EF代理对象,它似乎是用于延迟加载的。

The solution is to control the return type of Tags, by ending use of the Anonymous class:

解决方案是通过终止使用匿名类来控制标记的返回类型:

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

Now select into this and it all works:

现在选择这个,所有的工作:

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

#1


29  

While the above answers are true, note that when trying to use it after a select statement one has to call AsQueryable() explicitly, otherwise the compiler will assume that we are trying to use IEnumerable methods, which expect a Func and not Expression<Func>.

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

This was probably the issue of the original poster, as otherwise the compiler will complain most of the time that it is looking for Expression<Func> and not Func.

这可能是原始海报的问题,否则编译器会抱怨大部分时间都在寻找表达式 而不是Func。

Demo: The following will fail:

演示:以下将失败:

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

While the following will work:

下面的工作将会:

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

#2


24  

After creating the bounty (rats!), I found this answer, which solved my problem. (My problem involved a .Any() call, which is a little more complicated than this question...)

在创造了奖赏(老鼠!)之后,我找到了这个答案,它解决了我的问题。(我的问题涉及a .Any()电话,这比这个问题稍微复杂一点……)

In short, here's your answer:

简而言之,你的答案是:

IQueryable<Organization> query = context.Organizations;

Expression<Func<Reservation, bool>> expr = r => !r.IsDeleted;

query.Select(o => new { Reservations = o.Reservations.Where(expr) })
  .ToList();

Read the referenced answer for an explanation of why you need the local variable expr, and you can't directly reference another method of return type Expression<Func<Reservation, bool>>.

阅读参考答案,解释为什么需要本地变量expr,而不能直接引用另一种返回类型表达式 >。

#3


16  

Thanks for pinging me. I guess I was on the right track after all.

谢谢你联系我。我想我毕竟是在正确的轨道上。

Anyway, to reiterate, LINQ to Entities (thanks to Jon Skeet for correcting me when I got mixed up in my own thought process in the comments) operates on Expression Trees; it allows for a projection to translate the lambda expression to SQL by the QueryProvider.

无论如何,要重申的是,LINQ to实体(感谢Jon Skeet在我在评论中对我的想法进行了混淆)对表达式树进行了操作;它允许投影将lambda表达式转换为QueryProvider。

Regular Func<> works well for LINQ to Objects.

普通的Func<>在LINQ to Objects中很好用。

So in this case, when you're using the Entity Framework, any predicate passed to the EF's IQueryable has to be the Expression<Func<>>.

在这种情况下,当使用实体框架时,传递给EF的任何谓词都必须是表达式 >。

#4


3  

I just experienced this issue in a different scenario.

我只是在不同的情况下经历了这个问题。

I have a static class full of Expression predicates which I can then combine or pass to an EF query. One of them was:

我有一个充满表达式谓词的静态类,我可以将其合并或传递到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);
    }

This was throwing the 1025 error due to the Contains method group call. The entity framework expected an Expression and found a method group, which resulted in the error. Converting the code to use a lambda (which can be implicitly cast to an Expression) fixed the error

这是由于包含方法组调用导致的1025错误。实体框架期望一个表达式并找到一个方法组,结果导致错误。将代码转换为使用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));
    }

Aside: I then simplified the expression to ce => ce.Event.AttendeeStatuses.Any(a => a.ClientId == ce.Client.Id && statuses.Contains(a.Status.Value));

旁白:然后将表达式简化为ce => . event . attendeestatuse。(= >。ClientId = = ce.Client。Id & & statuses.Contains(a.Status.Value));

#5


0  

Had a similar problem. Library of ViewModels that look like this:

有一个类似的问题。像这样的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,
    };

This works:

如此:

var tags = await db.Tags.Take(10).Select(TagViewModel.Select)
    .ToArrayAsync();

But, this won't compile:

但是,这不会编译:

var post = await db.Posts.Take(10)
    .Select(p => new {
        Post = p,
        Tags = p.Tags.Select(pt => pt.Tag).Select(TagViewModel.Select)
    })
    .ToArrayAsync();

Because the second .Select is a mess - the first one is actually called off of an ICollection, which is not IQueryable, so it consumes that first Expression as a plain Func, not Expression<Func.... That returns IEnumerable<..., as discussed on this page. So .AsQueryable() to the rescue:

因为第二个。select是一个混乱,第一个是被取消的ICollection,它不是IQueryable,所以它将第一个表达式作为一个普通的Func,而不是表达式 返回ienumerable>

var post = await db.Posts.Take(10)
    .Select(p => new {
        Post = p,
        Tags = p.Tags.Select(pt => pt.Tag).AsQueryable()
            .Select(TagViewModel.Select)
    })
    .ToArrayAsync();

But that creates a new, weirder problem: Either I get Internal Framework...Error 1025, or I get the post variable with a fully loaded .Post property, but the .Tags property has an EF proxy object that seems to be used for Lazy-Loading.

但这创造了一个新的更奇怪的问题:要么我得到内部框架……错误1025,或者我用一个完全加载的. post属性获得post变量,但是. tags属性有一个EF代理对象,它似乎是用于延迟加载的。

The solution is to control the return type of Tags, by ending use of the Anonymous class:

解决方案是通过终止使用匿名类来控制标记的返回类型:

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

Now select into this and it all works:

现在选择这个,所有的工作:

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