[英]Entity Framework DbContext: Value cannot be null, parameter name source
I've started out using the CodeFirst approach in the entity framework.我已经开始在实体框架中使用 CodeFirst 方法。
When running my code I am unable to perform any operation on the DbSets within the DbContext - ProductsDb运行我的代码时,我无法对 DbContext - ProductsDb 中的 DbSet 执行任何操作
I have checked the connection string and I think it is correct but attempting to perform operation results in the error我检查了连接字符串,我认为它是正确的,但尝试执行操作导致错误
Value cannot be null, parameter source.值不能为空,参数来源。
Here is the ProductsDb class这是 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;
}
The connection string is defined in the app.config as follows:连接字符串在 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>
The code that throws the error is:抛出错误的代码是:
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;
}
All of the product classes are plain old C# classes.所有产品类都是普通的旧 C# 类。
Any help would be really appreciated, I'm starting to pull my hair out.任何帮助将不胜感激,我开始拉我的头发。 Never have any problems when writing Sql queries.编写 Sql 查询时永远不会有任何问题。
UPDATE: Copy Paste error the GetAProduct method has been altered.更新:复制粘贴错误 GetAProduct 方法已被更改。
You should define properties instead of fields for sets in your context class.您应该为上下文类中的集合定义属性而不是字段。 So, instead of fields所以,而不是字段
public DbSet<AProduct> AProducts;
You should use properties你应该使用属性
public DbSet<AProduct> AProducts { get; set; }
Because Entity Framework looks for properties.因为实体框架会查找属性。 If you will explore sources of DbContext
class, you will see, that in constructor in searches for declared set properties and initializes them:如果您将探索DbContext
类的来源,您将看到,在构造函数中搜索声明的设置属性并初始化它们:
private void DiscoverAndInitializeSets()
{
new DbSetDiscoveryService(this).InitializeSets();
}
This set discover service looks only for properties:此集合发现服务仅查找属性:
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)
{
// ...
}
If you will declare simple field of DbSet<T>
type, EF will skip it's initialization, and field will have value null
after context is created.如果您将声明DbSet<T>
类型的简单字段,EF 将跳过它的初始化,并且在创建上下文后字段的值为null
。 Thats why where enumerator was throwing null source
exception here:这就是为什么枚举器在这里抛出null source
异常的原因:
productsDb.AProducts.Where(a => a.Id== id)
I had the same error message though the cause was different: I'd made all of the POCOs (and their properties) that were being used by the DbContext internal
instead of public
.尽管原因不同,但我收到了相同的错误消息:我制作了 DbContext internal
使用的所有 POCO(及其属性),而不是public
。 As Sergey Berezovskiy has demonstrated in his answer, EF requires all class members to be public properties to initalise them.正如 Sergey Berezovskiy 在他的回答中所证明的那样,EF 要求所有类成员都是公共属性来初始化它们。 Changing them to public
fixed the error straight away.将它们更改为public
修复了错误。
For future readers:对于未来的读者:
I have this issue trying to make a "read only" DbContext.我在尝试制作“只读”DbContext 时遇到了这个问题。 (This specific project is all about "reports"). (这个特定的项目都是关于“报告”的)。 and wanting to expose only IQueryable (not DbSet).并且只想公开 IQueryable(而不是 DbSet)。
My original (causing this issue) code looked like this:我的原始(导致此问题)代码如下所示:
public IQueryable<OrganizationEntity> Organizations { get; set; }
public IQueryable<DepartmentEntity> Departments { get; set; }
My altered code looked like this.我修改过的代码看起来像这样。
internal DbSet<OrganizationEntity> InternalOrganizations { get; set; }
internal DbSet<DepartmentEntity> InternalDepartments { get; set; }
public IQueryable<OrganizationEntity> Organizations => this.InternalOrganizations.AsNoTracking();
public IQueryable<DepartmentEntity> Departments => this.InternalApplicationDetails.AsNoTracking();
This is now working.这是现在工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.