繁体   English   中英

具有EF6导航属性过滤器的C#ODataQueryOptions。 System.ArgumentNullException:值不能为null。 参数名称:类型

[英]C# ODataQueryOptions with EF6 navigation property filters. System.ArgumentNullException : Value cannot be null. Parameter name: type

我有一个家长班

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; }
}

和一个儿童班

public class AuditDate : BaseModel
{
    public int Duration { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate{ get; set; }
}

现在,这些用于实体框架(版本6)CF方法中,其中

公共虚拟DbSet审核{ 组; }

被宣布。 然后,我使用下面的代码来应用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>,在这种情况下,T为Audit

ODataQueryOptions oDataQueryOptions = PrepareOdataQueryOption(oDataUri);
IQueryable Value = oDataQueryOptions.ApplyTo(dbSet);

但是当我使用以下oData uri调用它时

http:// localhost:7071 / api / Audit ?$ expand = AuditDates($ filter = Id eq 1)

我在声明IQueryable Value = oDataQueryOptions.ApplyTo(dbSet);

System.ArgumentNullException:值不能为null。 参数名称:在Microsoft.OData.Edm.EdmUtil.CheckArgumentNull [T](T value,String parameterName)处键入。 Microsoft.OData.Edm:值不能为null。

仅当我尝试过滤子记录时才发生这种情况, 以便我只能检索到很少的子记录,而不是全部。

以下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 = Id,名称
  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将实体集注册为模型的一部分。

其次,由于仅声明了父对象,而没有声明导航属性,因此无法找到子记录的类型(因此,“参数名称:类型”中的错误)。

我假设ODataModelbuilder将自动选择AuditDate实体集(就像实体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");
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM