带有 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 按预期工作(错误仅出现在对导航属性进行筛选的情况下):

  1. http://localhost:7071/api/Audit?$expand=AuditDates
  2. http://localhost:7071/api/Audit?$expand=AuditDates&$filter=AuditDates/any(auditDate: auditDate/Id eq 1)
  3. http://localhost:7071/api/Audit?$select=身份证,姓名
  4. 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");
    ...
}