【发布时间】:2012-04-23 19:20:34
【问题描述】:
我正在构建一个使用 Mongo 和官方 C# 驱动程序的应用程序。使用接口和泛型类型约束时我遇到了一个奇怪的问题。考虑以下几点:
interface IMongoObject
{
BsonObjectId Id { get; set; }
string Name { get; set; }
}
class MongoObject : IMongoObject
{
public BsonObjectId Id { get; set; }
public string Name { get; set; }
}
class Program
{
MongoServer m_db;
string m_dbName;
protected void Save<T>(T entity) where T : IMongoObject
{
GetDatabase().GetCollection<T>(typeof(T).Name).Save(entity);
}
protected T Get<T>(string name) where T : IMongoObject
{
Type t = typeof(T);
// Throws
return GetDatabase().GetCollection<T>(typeof(T).Name).AsQueryable().Where(o => o.Name == name).FirstOrDefault();
}
protected MongoDatabase GetDatabase()
{
if (m_db == null)
{
var conString = "mongodb://localhost/MongoTest";
MongoUrl url = new MongoUrl(conString);
m_dbName = url.DatabaseName;
m_db = MongoServer.Create(url);
}
return m_db.GetDatabase(m_dbName);
}
void Run()
{
MongoObject o = new MongoObject();
o.Name = "Foo";
Save(o);
MongoObject b = Get<MongoObject>("Foo");
Console.ReadKey();
}
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
}
除了对 Get(...) 的调用之外,一切正常。使用官方驱动程序,我从 SelectQuery.cs 中的函数 private BsonSerializationInfo GetSerializationInfoMember(IBsonSerializer serializer, MemberExpression memberExpression) 中的调用 var memberSerializationInfo = containingSerializationInfo.Serializer.GetMemberSerializationInfo(memberName); 中得到一个空引用异常。
如果我切换到使用 FluentMongo 进行 LINQ,我会收到一条消息说
“只能为类注册判别器,不能为接口 MyLib.Services.IRepoData 注册。”
这和这家伙基本一样:
FluentMongo throwing error all of a sudden
我知道 Mongo 驱动程序在抱怨,因为它不知道 IMongoObject 是什么。我不明白的是为什么 where 调用中的表达式将“o”视为 IMongoObject 类型而不是 MongoObject 类型(通过调试器确认这是正在发生的事情),就是这样。
如果我改用抽象基类,一切正常。我不知道该怎么做,因为不是所有的“MongoObjects”
谢谢
【问题讨论】:
标签: c# mongodb fluent-mongo