![](/img/trans.png)
[英]Getting error on POST with Entity Framework - Value cannot be null. Parameter name: source
[英]Entity Framework DbContext: Value cannot be null, parameter name source
我已经开始在实体框架中使用 CodeFirst 方法。
运行我的代码时,我无法对 DbContext - ProductsDb 中的 DbSet 执行任何操作
我检查了连接字符串,我认为它是正确的,但尝试执行操作导致错误
值不能为空,参数来源。
这是 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# 类。
任何帮助将不胜感激,我开始拉我的头发。 编写 Sql 查询时永远不会有任何问题。
更新:复制粘贴错误 GetAProduct 方法已被更改。
您应该为上下文类中的集合定义属性而不是字段。 所以,而不是字段
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)
尽管原因不同,但我收到了相同的错误消息:我制作了 DbContext internal
使用的所有 POCO(及其属性),而不是public
。 正如 Sergey Berezovskiy 在他的回答中所证明的那样,EF 要求所有类成员都是公共属性来初始化它们。 将它们更改为public
修复了错误。
对于未来的读者:
我在尝试制作“只读”DbContext 时遇到了这个问题。 (这个特定的项目都是关于“报告”的)。 并且只想公开 IQueryable(而不是 DbSet)。
我的原始(导致此问题)代码如下所示:
public IQueryable<OrganizationEntity> Organizations { get; set; }
public IQueryable<DepartmentEntity> Departments { get; set; }
我修改过的代码看起来像这样。
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();
这是现在工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.