我正在構建一個使用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