我使用的方法返回类型为IMongoQueryable<TEntity>
的可查询对象。当mongodb数据库抛出错误时,此方法的结果返回default(IMongoQueryable<TEntity>)
。我想用一个空的可查询对象代替该行,而不是默认结果,但是MongoDb Linq库不提供任何内容。
//Sample of the code
public IMongoQueryable<TEntity> AllQueryable<TEntity>(AggregateOptions options = null) where TEntity : Entity
{
try
{
return GetCollection<TEntity>().AsQueryable(options);
}
catch (Exception ex)
{
return default(IMongoQueryable<TEntity>);
}
}
所以,如何实现与Enumerable.Empty<TEntity>().AsQueryable()
或类似IEnumerable<TEntity>().AsMongoQueryable()
之类的自定义类型?
//I need something like this
public IMongoQueryable<TEntity> AllQueryable<TEntity>(AggregateOptions options = null) where TEntity : Entity
{
try
{
return GetCollection<TEntity>().AsQueryable(options);
}
catch (Exception ex)
{
return Enumerable.Empty<TEntity>().AsMongoQueryable();
}
}
当调试C#应用程序时,您会注意到在MongoDB集合上运行.AsQueryable<T>
会返回MongoQueryableImpl类的实例,该实例在MongoDB.Driver.Linq
命名空间中为internal。您可以尝试使用反射实例化该类,但是有一种更简单的方法。
您可以按照Null Object设计模式来实现自己的IMongoQueryable<T>
接口实现。
接口需要一些方法,但是您可以使大多数方法保持未实现的状态-您将永远不需要它们。因此,您的EmptyMongoQueryable<T>
可能看起来像这样:
public class EmptyMongoQueryable<T> : IMongoQueryable<T>
{
public Expression Expression => Expression.Empty();
public Type ElementType => typeof(T);
public IQueryProvider Provider => throw new NotImplementedException();
public IEnumerator<T> GetEnumerator()
{
yield break;
}
public QueryableExecutionModel GetExecutionModel() => throw new NotImplementedException();
public IAsyncCursor<T> ToCursor(CancellationToken cancellationToken = default(CancellationToken)) => throw new NotImplementedException();
public Task<IAsyncCursor<T>> ToCursorAsync(CancellationToken cancellationToken = default(CancellationToken)) => throw new NotImplementedException();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
然后您可以运行以下代码:
var queryable = new EmptyMongoQueryable<YourType>();
var emptyList = queryable.ToList();