C# Mongo DB中LINQ Where子句中的接口

C# Mongo DB中LINQ Where子句中的接口,c#,linq,mongodb,interface,where-clause,C#,Linq,Mongodb,Interface,Where Clause,让我们从简单的例子开始。我和我的团队正在学校的软件项目中工作。我们正在使用MongoDB来存储产品,我们正在使用接口,以便将来可以更改实现。产品看起来像这样 interface IProduct { long ID { get; set; } string Name { get; set; } } class MongoProduct : IProduct { [BsonId] public long ID { get; set; } public st

让我们从简单的例子开始。我和我的团队正在学校的软件项目中工作。我们正在使用MongoDB来存储产品,我们正在使用接口,以便将来可以更改实现。产品看起来像这样

interface IProduct
{
    long ID { get; set; }
    string Name { get; set; }
}

class MongoProduct : IProduct
{
    [BsonId]
    public long ID { get; set; }
    public string Name { get; set; }
}
我们有测试接口

interface ITestProbe
{
    IQueryable<IProduct> FindProducts(Expression<Func<IProduct, bool>> condition);
}
接口ITestProbe
{
可查询的FindProducts(表达条件);
}
并假设这个实现

class MongoRepository : ITestProbe
{
    public MongoRepository()
    {
        _client = new MongoClient();
        _server = _client.GetServer();
        _db = _server.GetDatabase(_dbName);
        _collection = _db.GetCollection(_collectionName);
    }

    public const string _dbName = "MongoPlayground";
    public const string _collectionName = "Products";

    protected MongoClient _client;
    protected MongoServer _server;
    protected MongoDatabase _db;
    protected MongoCollection _collection;

    public IQueryable<IProduct> FindProducts(System.Linq.Expressions.Expression<Func<IProduct, bool>> condition)
    {
        return _collection.AsQueryable<MongoProduct>().Where<IProduct>(condition);
    }
}
class MongoRepository:ITestProbe
{
公共MongoRepository()
{
_客户端=新的MongoClient();
_服务器=_client.GetServer();
_db=_server.GetDatabase(_dbName);
_collection=\u db.GetCollection(\u collectionName);
}
公共常量字符串_dbName=“MongoPlayground”;
public const string\u collectionName=“产品”;
受保护的MongoClient\u客户端;
受保护的MongoServer\u服务器;
受保护的MongoDatabase_db;
受保护的MongoCollection\u collection;
公共IQueryable FindProducts(System.Linq.Expressions.Expression条件)
{
返回_collection.AsQueryable().Where(条件);
}
}
这将不起作用,因为“无法确定表达式:p.Name的序列化信息”。按如下方式进行测试时:

class Program
{
    static void GenerateProducts()
    {
        var _client = new MongoClient();
        var _server = _client.GetServer();
        var _db = _server.GetDatabase("MongoPlayground");
        var _collection = _db.GetCollection("Products");

        MongoProduct[] products = new MongoProduct[]{
            new MongoProduct(){ID=1,Name="A"},
            new MongoProduct(){ID=2,Name="B"},
            new MongoProduct(){ID=3,Name="C"},
            new MongoProduct(){ID=4,Name="D"}
        };

        foreach (var p in products)
        {
            _collection.Insert<MongoProduct>(p);
        }
    }

    static void Main(string[] args)
    {
        //GenerateProducts();
        MongoRepository r = new MongoRepository();
        var products = r.FindProducts(p => p.Name == "C");
        foreach (var p in products)
        {
            Console.WriteLine(p.Name);
        }
    }
}
类程序
{
静态void GenerateProducts()
{
var_client=new MongoClient();
var_server=_client.GetServer();
var\u db=\u server.GetDatabase(“MongoPlayground”);
var_collection=_db.GetCollection(“产品”);
MongoProduct[]产品=新的MongoProduct[]{
新的MongoProduct(){ID=1,Name=“A”},
新的MongoProduct(){ID=2,Name=“B”},
新的MongoProduct(){ID=3,Name=“C”},
新建MongoProduct(){ID=4,Name=“D”}
};
foreach(产品中的var p)
{
_收款。插入(p);
}
}
静态void Main(字符串[]参数)
{
//生成产品();
MongoRepository r=新的MongoRepository();
var products=r.FindProducts(p=>p.Name==“C”);
foreach(产品中的var p)
{
Console.WriteLine(p.Name);
}
}
}
此问题的解决方案是将表达式从IPProduct转换为MongoProduct(示例如何执行此操作在stackoverflow的另一个主题中)

然后我们可以写:

var switched = Translate<IProduct, MongoProduct>(condition);
return _collection.AsQueryable<MongoProduct>().Where<MongoProduct>(switched);
var开关=转换(条件);
返回_collection.AsQueryable().Where(已切换);

所以,我的问题是,还有其他方法吗?我缺少什么吗?我试图用谷歌搜索解决方案,但什么也没找到。我不明白为什么当MongoProduct是IPProduct类型时,我们不能在Where函数中使用IPProduct。这个“翻译”解决方案对我来说似乎有点笨拙。

我真的不知道解决方案,但你试过s吗这个问题的解决方法?您不能在Mongo驱动程序中使用ToEnumerable after AsQueryable。