首页 文章

如何解决“内部.NET Framework数据提供程序错误1025” .

提问于
浏览
5

我首先使用Entity Framework 4.3,POCO,数据库,我收到以下错误:

Internal .NET Framework Data Provider error 1025.

问题:我认为我的查询表达了我的意图,但我似乎遇到了这个错误,所以我想知道是否有人知道如何以不同的方式构建我的查询来解决这个错误?

这是场景......

我有一个SQL Server 2008数据库,有2个表--A和B:

A

  • AId(int - not null - identity - primary key)

  • AName(nvarchar(10) - not null)

B

  • BId(int - not null - identity - primary key)

  • SomeName(nvarchar(10) - not null)

  • AId(int - not null - 连接到表A中的AId的外键)

然后我像这样定义上下文:

public class DatabaseContext : DbContext
{
    public DatabaseContext(string name)
        : base(name)
    {
        Configuration.AutoDetectChangesEnabled = false;
        As = Set<A>();
        Bs = Set<B>();
    }

    public DbSet<A> As { get; private set; }
    public DbSet<B> Bs { get; private set; }
}

实体类如下:

public class A
{
    public int AId { get; set; }
    public string AName { get; set; }
    public virtual ICollection<B> Bs { get; private set; }

    public void AddB(B b)
    {
        if (b == null)
        {
            throw new ArgumentNullException("b");
        }

        if (Bs == null)
        {
            Bs = new List<B>();
        }

        if (!Bs.Contains(b))
        {
            Bs.Add(b);
        }

        b.A = this;
    }
}

public class B
{
    public int BId { get; set; }
    public A A { get; set; }
    public string SomeName { get; set; }
}

现在查询...

我想要的是所有的As,其中每个“B SomeName”都在提供的名称列表中,所以我这样做:

var names = new[] {"Name1", "Name2"};

var ctx = new DatabaseContext("EFPlayingEntities");
var res = ctx.As.Where(a => a.Bs.Select(b => b.SomeName).All(names.Contains));

// Here I evaluate the query and I get:
//   Internal .NET Framework Data Provider error 1025.
Console.WriteLine(res.Count());

要明确我的意思,如果表数据如下所示:

AId,AName
1,A1
2,A2
3,A3
4,A4

BId,SomeName,AId
1,Name1,1
2,Name2,1
3,Name1,2
4,Name1,3
5,Name3,3
6,Name1,4
7,Name2,4

我希望能够回到A1,A2和A4(所以上面的计数将返回3) .

3 回答

  • 8

    我已经找到了解决方案,万一有人感兴趣 . 执行以下操作是等效的,不会导致问题中的异常:

    var res = ctx
        .Bs
        .GroupBy(b => b.A)
        .Where(g => g.All(b => names.Contains(b.SomeName)))
        .Select(g => g.Key);
    

    我不知道这是不是最好的方式!?

  • 2

    这种情况发生的原因很微妙 .

    需要使用 Expression 调用 Queryable.All . 传入方法'reference'会创建一个委托,随后, Enumerable.All 成为候选而不是预期的 Queryable.All .

    这就是您作为答案发布的解决方案正常工作的原因 .

    EDIT

    因此,如果您将此语句写为此语句,它将毫无例外地起作用:

    var res = ctx.As.Where(
      a => a.Bs.Select(b => b.SomeName).All(b => names.Contains(b)));
    
  • 1

    查询的语义对我来说很好;显然,获取内部提供程序错误不是预期的行为!我本来期望一些关于EF的更明确的消息不能将你的查询翻译成商店操作,如果这实际上是问题所在 .

    另一种做你想做的事情是:

    var names = new[] {"Name1", "Name2"};
    var nameCount = names.Length;
    
    var ctx = new DatabaseContext("EFPlayingEntities");
    var result = ctx.As
        .Where(a => a.Bs
                     .Select(b => b.SomeName)
                     .Intersect(names)
                     .Count() == a.Bs.Count());
    

    (得到每个 A ,使其 B s'名称与固定列表相交,给出所有的 B

    虽然我没有试过这个,看看EF能否成功翻译 .

    其他方式:

    var names = new[] {"Name1", "Name2"};
    
    var ctx = new DatabaseContext("EFPlayingEntities");
    var result = ctx.As
        .Where(a => !a.Bs.Select(b => b.SomeName).Except(names).Any());
    

    (获取每个 A ,以便通过取出固定列表将其 B 的名称列表减少为空)

    还没有尝试过 .

相关问题