2012-03-01 73 views
5

我4.3,POCO,數據庫首先使用實體​​框架和我收到以下錯誤:如何解決「內部.NET Framework數據提供程序錯誤1025」?

內部的.NET Framework數據提供程序錯誤1025

問題:我認爲我的查詢表達我的意圖,但我似乎遇到這個錯誤,所以我想知道如果有人知道我可以如何構建我的查詢不同來解決這個錯誤?

這裏的情景......

我有了2桌的SQL Server 2008數據庫 - A和B:

一個

  • 援助(INT - 不null - 身份 - 主鍵)
  • AName(nvarchar(10) - 非null)

  • 出價(INT - 不爲空 - 身份 - 主鍵)
  • SomeName(nvarchar的(10) - 不爲空)
  • 助劑(INT - 不爲空 - 外鍵連接在表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; } 
} 

現在的查詢...

我要的是所有的作爲,每一個「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)。

+0

你看看內部異常? – 2012-03-01 09:02:22

+0

內部異常是空:-( – kmp 2012-03-01 09:06:00

+0

names.Contains是無效代碼,不知道如何編譯,我懷疑你想使用相交(),而不是所有的()。 – 2012-03-01 12:51:50

回答

8

之所以出現這種情況的原因是微妙的。

Queryable.All需要與Expression被調用。只傳入參考方法會創建一個委託,隨後,Enumerable.All成爲候選人,而不是預期的Queryable.All

這就是爲什麼你的解決方案,你張貼的答案正常工作。

編輯

所以,如果你寫的聲明,因爲這,它會工作無一例外:

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

哇!因此即使.All(b => names.Contains(b))在功能上(我的意思是它的作用,而不是它是如何做的)等價於.All(names.Contains)你所說的是底層機制是不同的,當它評估表達式樹時,我碰到了EF中的一個錯誤?我只是試了一下,這個「ctx.As.Where(a => a.Bs.Select(b => b.SomeName).All(b => names.Contains(b)))」實際上沒有錯誤地執行!謝謝! – kmp 2012-03-01 14:47:38

+0

我希望你不要介意,我在你的回答中加了一點,這樣如果有其他人遇到這個問題,他們會馬上看到你提出的改變。 – kmp 2012-03-01 14:51:44

+0

@ user1039947:沒問題:)這不是EF錯誤,而是C#表達式編譯器缺少的功能。 – leppie 2012-03-01 16:43:26

2

我已經爲此制定瞭解決方案,以防有人感興趣。執行以下操作,相當於在該問題不會導致異常:

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

我不知道這是否是,雖然最好的方式!?

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

雖然我的天堂試試看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 S'名稱的列表被取出固定列表化爲烏有)

也未嘗試過。

+0

感謝您的回答,並且都毫無例外地執行正常!但是,您的任何解決方案都不會與我需要的功能完全匹配,因爲它們還會返回任何具有Bs集合的A與我傳入的名稱集合的子集。在我的示例數據中,我預計A2也會被返回,因爲它裏面有「Name1」。 – kmp 2012-03-01 13:36:41

+0

@user oops,有錯誤的子集;更新了我的答案。我認爲'Except'方式現在肯定是兩者中最好的。是的,所有的:你的原創,你的答案和我的兩種方式,都具有相同的語義 - 選擇純粹是品味的問題,當然EF是否可以成功翻譯... – AakashM 2012-03-01 14:27:21

相關問題