Я создаю приложение, которое использует 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 (...). Используя официальный драйвер, я получаю исключение нулевой ссылки из вызова var memberSerializationInfo = containingSerializationInfo.Serializer.GetMemberSerializationInfo(memberName);
в функции private BsonSerializationInfo GetSerializationInfoMember(IBsonSerializer serializer, MemberExpression memberExpression)
в SelectQuery.cs.
Если я перейти на использование FluentMongo для LINQ, я получаю сообщение о том,
«Дискриминаторы могут быть зарегистрированы только для классов, а не для интерфейса MyLib.Services.IRepoData.»
Это в основном так же, как этот парень:
FluentMongo throwing error all of a sudden
Я понимаю, что водитель Монго жалуется, потому что он не знает, что IMongoObject есть. То, что я не понимаю, - это то, почему выражение внутри вызываемого вызова видит «о» как тип IMongoObject, а не типа MongoObject (подтвержденный отладчиком, это то, что происходит), что и есть.
Если я переключусь на использование абстрактного базового класса, все работает отлично. Я не то, что делать это, потому что не все «MongoObjects»
Благодарности
большое спасибо за ответ. Его странно, как компилятор чувствует необходимость конвертировать в IMongoObject, когда он четко знает фактический тип T и что T реализует IMongoObject. Из интереса я попытался добавить экспликативный прилив к T в выражение, которое он преобразует в (((MongoObject) (IMongoObject)) o) .Name. Полезно; o). Разделение WRT проблем, приведенный выше код был просто примером демонстрации проблемы - фактический код имеет 2 дерева объектов, как вы предлагаете. Я буду следить за выпуском исправления. Благодарю. – didster