我正在构建一个使用Mongo和官方C#驱动程序的应用程序。我在使用接口和泛型类型约束时遇到了一个奇怪的问题。考虑以下内容:MongoDB C#驱动程序抛出与LINQ的异常
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
据我所知,蒙哥司机抱怨,因为它不知道IMongoObject是什么。我不明白的是,为什么表达式内的where调用将“o”看作类型为IMongoObject的类型不是MongoObject类型(用调试器确认这是发生了什么),这就是它的原因。
如果我切换到使用抽象基类,它一切正常。我不该做什么这一点,因为不是所有的“MongoObjects”
感谢
非常感谢您的答复。它奇怪的是,当它明确知道T的实际类型并且T实现IMongoObject时,编译器觉得需要转换为IMongoObject。出于兴趣,我尝试向T转换为(((MongoObject)(IMongoObject))o).Name的表达式添加一个明确的转换。有帮助; o)。 WRT分离问题,上面的代码只是一个演示问题的例子 - 实际代码有2个对象树,正如你所建议的那样。我会密切关注修复的发布。谢谢。 – didster 2012-04-25 06:51:12