2013-07-02 74 views
2

我已經開始在實體框架中使用CodeFirst方法。實體框架DbContext:值不能爲空,參數名稱來源

當運行我的代碼,我不能履行對的DbContext內DbSets任何操作 - ProductsDb

我檢查了連接字符串,我認爲這是正確的,但試圖在錯誤執行的操作結果

值不能爲空,參數源。

這裏是ProductsDb類

public class ProductsDb : DbContext 
{ 
    public ProductsDb(string connectionString) : base(connectionString) 
    {    
    } 

    public ProductsDb() 
    {    
    } 

    public DbSet<AProduct> AProducts; 
    public DbSet<BProduct> BProducts; 
    public DbSet<CProduct> CProducts; 
    public DbSet<DProduct> DProducts; 
} 

連接字符串是在App.config定義如下:

<?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 
    <connectionStrings> 
    <add name="ProductsDb" providerName="System.Data.SqlClient" 
     connectionString="Data Source=MyPC\DEV;Initial Catalog=Test;User ID=sa; 
     Password=pass;" /> 
    </connectionStrings> 
    </configuration> 

拋出的錯誤的代碼是:

GetAProduct(string id) 
{ 
    AProduct aProduct = null; 

    using (ProductsDb productsDb = new ProductsDb()) 
    { 
     aProduct = (from a in productsDb.AProducts 
        where a.Id== id 
        select a).FirstOrDefault(); 
    } 

    return aProduct; 
} 

所有的產品類都是普通的舊C#cl驢。

任何幫助將非常感激,我開始拉我的頭髮。 編寫Sql查詢時不會有任何問題。

更新:複製粘貼錯誤GetAProduct方法已被更改。

+2

productsDb,哪裏來的? –

+0

發佈你正在初始化'productsDb'的代碼 – SOfanatic

+0

對不起,編輯文章 –

回答

10

您應該爲上下文類中的集合定義屬性而不是字段。所以,與其領域

public DbSet<AProduct> AProducts; 

你應該因爲實體框架查找屬性使用屬性

public DbSet<AProduct> AProducts { get; set; } 

。如果你將探索DbContext類的來源,你會看到,在構造函數中搜索聲明的屬性和它們初始化:

private void DiscoverAndInitializeSets() 
{ 
    new DbSetDiscoveryService(this).InitializeSets(); 
} 

這組發現服務只查找屬性:

var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; 
var properties = 
    from p in this._context.GetType().GetProperties(flags) 
    where (p.GetIndexParameters().Length == 0) && 
     (p.DeclaringType != typeof(DbContext)) 
    select p); 

foreach(PropertyInfo info in properties) 
{ 
    // ... 
} 

如果您將聲明DbSet<T>類型的簡單字段,EF將跳過它的初始化,並且在創建上下文後字段的值將爲null。這就是爲什麼在那裏枚舉被扔null source例外這裏:

productsDb.AProducts.Where(a => a.Id== id) 
+0

我確定這是解決方案;) –

+0

@JoffreyKern這絕對是:) –

+0

是的,就是這樣。現在恨我自己很多。什麼時候有公共領域好嗎? –

2

我有同樣的錯誤消息,但原因是不同的: 我犯了所有正在使用的的DbContext的波蘇斯(和它們的屬性)的internal而不是public。正如Sergey Berezovskiy在他的回答中所表明的那樣,EF要求所有的班級成員都是公共財產,以使他們活躍起來。將它們更改爲public可以立即糾正錯誤。

相關問題