带有 EF6 导航 属性 过滤器的 C# ODataQueryOptions。 System.ArgumentNullException : 值不能为空。参数名称:类型
C# ODataQueryOptions with EF6 navigation property filters. System.ArgumentNullException : Value cannot be null. Parameter name: type
我有一个parentclass
public class Audit : BaseModel//Properties are intentionally made non virtual
{
public string Name { get; set; }
public int FacilityId { get; set; }
public string Passcode { get; set; }
public ICollection<AuditDate> AuditDates { get; set; }
}
和一个childclass
public class AuditDate : BaseModel
{
public int Duration { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate{ get; set; }
}
现在,这些用于 entity framework(版本 6)CF 方法,其中
public virtual DbSet Audits { get; set; }
已声明。然后,我使用下面的代码来应用 oData 查询-
准备好的 ODataQueryOptions:
private ODataQueryOptions PrepareOdataQueryOption(Uri oDataUri)
{
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.EnableDependencyInjection();
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, oDataUri);
httpRequestMessage.Properties[HttpPropertyKeys.HttpConfigurationKey] = httpConfiguration;
ODataModelBuilder oDataModelBuilder = new ODataConventionModelBuilder();
oDataModelBuilder.EntityType<TDomainModel>();
ODataQueryContext oDataQueryContext = new ODataQueryContext(oDataModelBuilder.GetEdmModel(), typeof(TDomainModel), null);
return new ODataQueryOptions(oDataQueryContext, httpRequestMessage);
}
应用 ODataQueryOptions(dbSet 是 DbSet,在这种情况下 T 是 Audit )
ODataQueryOptions oDataQueryOptions = PrepareOdataQueryOption(oDataUri);
IQueryable Value = oDataQueryOptions.ApplyTo(dbSet);
But when I call this using following oData uri
http://localhost:7071/api/Audit?$expand=AuditDates($filter=Id eq 1)
I get error at statement IQueryable Value = oDataQueryOptions.ApplyTo(dbSet);
System.ArgumentNullException : Value cannot be null. Parameter name: type at Microsoft.OData.Edm.EdmUtil.CheckArgumentNull[T](T value,String parameterName). Microsoft.OData.Edm: Value cannot be null.
This happens only when I try to filter child records so that I can
retrieve only few child records, not all.
以下 URI 按预期工作(错误仅出现在对导航属性进行筛选的情况下):
- http://localhost:7071/api/Audit?$expand=AuditDates
- http://localhost:7071/api/Audit?$expand=AuditDates&$filter=AuditDates/any(auditDate: auditDate/Id eq 1)
- http://localhost:7071/api/Audit?$select=身份证,姓名
- http://localhost:7071/api/Audit?$select=Id,Name&$expand=AuditDates($select=Id,StartDate)
谢谢!
问题出在以下函数(语句)中:
private ODataQueryOptions PrepareOdataQueryOption(Uri oDataUri)
{
...
oDataModelBuilder.EntityType<TDomainModel>();
...
}
首先,应该是EntitySet,而不是EntityType。 EntitySet 将实体集注册为模型的一部分。
其次,由于只声明了父对象,没有声明导航属性,因此无法找到子记录的类型(因此,"Parameter name: type" 中的错误)。
我假设 ODataModelbuilder 会自动选择 AuditDate 实体集(就像 entity Framework Code First 方法一样),但它没有。
我必须明确声明它。因此,我将上面的语句更改为以下语句(以匹配 DbContext)并且一切都开始工作了。
private ODataQueryOptions PrepareOdataQueryOption(Uri oDataUri)
{
...
oDataModelBuilder.EntitySet<Audit>("Audits");//Only parent domain model is required unless you want to filter navigation property rows
oDataModelBuilder.EntitySet<AuditDate>("AuditDates");
...
}
我有一个parentclass
public class Audit : BaseModel//Properties are intentionally made non virtual
{
public string Name { get; set; }
public int FacilityId { get; set; }
public string Passcode { get; set; }
public ICollection<AuditDate> AuditDates { get; set; }
}
和一个childclass
public class AuditDate : BaseModel
{
public int Duration { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate{ get; set; }
}
现在,这些用于 entity framework(版本 6)CF 方法,其中
public virtual DbSet Audits { get; set; }
已声明。然后,我使用下面的代码来应用 oData 查询-
准备好的 ODataQueryOptions:
private ODataQueryOptions PrepareOdataQueryOption(Uri oDataUri)
{
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.EnableDependencyInjection();
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, oDataUri);
httpRequestMessage.Properties[HttpPropertyKeys.HttpConfigurationKey] = httpConfiguration;
ODataModelBuilder oDataModelBuilder = new ODataConventionModelBuilder();
oDataModelBuilder.EntityType<TDomainModel>();
ODataQueryContext oDataQueryContext = new ODataQueryContext(oDataModelBuilder.GetEdmModel(), typeof(TDomainModel), null);
return new ODataQueryOptions(oDataQueryContext, httpRequestMessage);
}
应用 ODataQueryOptions(dbSet 是 DbSet
ODataQueryOptions oDataQueryOptions = PrepareOdataQueryOption(oDataUri);
IQueryable Value = oDataQueryOptions.ApplyTo(dbSet);
But when I call this using following oData uri
http://localhost:7071/api/Audit?$expand=AuditDates($filter=Id eq 1)
I get error at statement
IQueryable Value = oDataQueryOptions.ApplyTo(dbSet);
System.ArgumentNullException : Value cannot be null. Parameter name: type at Microsoft.OData.Edm.EdmUtil.CheckArgumentNull[T](T value,String parameterName). Microsoft.OData.Edm: Value cannot be null.
This happens only when I try to filter child records so that I can retrieve only few child records, not all.
以下 URI 按预期工作(错误仅出现在对导航属性进行筛选的情况下):
- http://localhost:7071/api/Audit?$expand=AuditDates
- http://localhost:7071/api/Audit?$expand=AuditDates&$filter=AuditDates/any(auditDate: auditDate/Id eq 1)
- http://localhost:7071/api/Audit?$select=身份证,姓名
- http://localhost:7071/api/Audit?$select=Id,Name&$expand=AuditDates($select=Id,StartDate)
谢谢!
问题出在以下函数(语句)中:
private ODataQueryOptions PrepareOdataQueryOption(Uri oDataUri)
{
...
oDataModelBuilder.EntityType<TDomainModel>();
...
}
首先,应该是EntitySet,而不是EntityType。 EntitySet 将实体集注册为模型的一部分。
其次,由于只声明了父对象,没有声明导航属性,因此无法找到子记录的类型(因此,"Parameter name: type" 中的错误)。
我假设 ODataModelbuilder 会自动选择 AuditDate 实体集(就像 entity Framework Code First 方法一样),但它没有。 我必须明确声明它。因此,我将上面的语句更改为以下语句(以匹配 DbContext)并且一切都开始工作了。
private ODataQueryOptions PrepareOdataQueryOption(Uri oDataUri)
{
...
oDataModelBuilder.EntitySet<Audit>("Audits");//Only parent domain model is required unless you want to filter navigation property rows
oDataModelBuilder.EntitySet<AuditDate>("AuditDates");
...
}