LinqKit与Azure DocumentDB

时间:2016-10-06 07:01:09

标签: c# linq azure azure-cosmosdb

我正在尝试使用LinqKit的PredicateBuilder和Azure DocumentDB来动态构建Where子句以进行搜​​索。例如,我已经定义了几个SearchModel对象,这些对象为单个存储库提供可查询字段。

 public class EmailEventSearchModel : SearchModel
{
    /// <summary>
    /// Search for events of a particular type
    /// </summary>
    public IList<EventType> Types { get; set; }

    /// <summary>
    /// search for events related to a specific user
    /// </summary>
    public string User { get; set; }

    /// <summary>
    /// search for events that occurred after this date and time (in UTC)
    /// </summary>
    public DateTime? StartDateTime { get; set; }

    /// <summary>
    /// search for events that occurred before this date and time (in UTC)
    /// </summary>
    public DateTime? EndDateTime { get; set; }

    ....

使用PredicateBuilder将这些对象转换为谓词并传递到包含DocumentDB集成的GenericRepository对象中:

    public override async Task<ISearchResult<EmailTemplate>> Get(ISearchModel model)
    {
        if(!(model is EmailTemplateSearchModel))
            throw new ArgumentException($"Expected a model of type EmailTemplateSearchModel but received {model.GetType().Name}.");

        var templateModel = model as EmailTemplateSearchModel;

        var builder = PredicateBuilder.New<EmailTemplate>();

        if (!string.IsNullOrEmpty(templateModel.Name))
            builder = builder.And(x => x.Name.Contains(templateModel.Name));

        if (!string.IsNullOrEmpty(templateModel.Body))
            builder = builder.And(x => x.Body.Contains(templateModel.Body));

        if (templateModel.AccountId.HasValue)
            builder = builder.And(x => x.AccountId == templateModel.AccountId.Value);

        if (templateModel.LegacyAccountId > 0)
            builder = builder.And(x => x.LegacyAccountId == templateModel.LegacyAccountId);

        if (templateModel.EventId.HasValue)
            builder = builder.And(x => x.EventId == templateModel.EventId);

        return await Get(builder, model);

在存储库中,我只是将谓词传递给Queryable对象:

            var result = Client.CreateDocumentQuery<TModel>(UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName), feedoptions)
            .Where(predicate)
            .AsDocumentQuery();

当只有一个搜索模型属性具有要搜索的值时,这非常有用。但是,当我有2个或更多属性(即我有要搜索的EventTypes和用户字符串)时,我收到错误Expression with NodeType 'Invoke' is not supported.

使用PredicateBuilder构建的谓词是否与Azure DocumentDB的.NET SDK兼容?如果没有,是否有更好的解决方案来构建动态查询?

0 个答案:

没有答案