2017-01-31 16 views
3

Я хочу иметь возможность проецировать другой тип при запросе MongoDB с использованием SDK C#.Проецирование на другой тип с использованием C# SDK

Например, ниже я хочу запросить коллекцию с помощью построителя фильтров (или выражения LINQ) для MyType, но я хочу проецировать результат MySubType.

var mySubTypes = Database 
    .GetCollection<MyType>("MyCollection") 
    .Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, documentId)) 
    .ProjectTo<MySubType>() // Project to another type?? 
    .ToList(); 

Можно представить себе MySubType быть подмножеством MyType, представлены с использованием наследования:

public class MyType : MySubType 
{ 
    [BsonElement("documents")] 
    public List<string> Documents { get; set; } 
} 

public class MySubType 
{ 
    [BsonElement("name")] 
    public string Name { get; set; } 
} 

Почему я хочу, чтобы это сделать?

Поскольку массив Documents очень велик и используется исключительно во время запроса (то есть для фильтрации) в рамках механизма базы данных. Извлечение и сериализация этого массива будет ненужной.

+0

Похоже, вы хотите Cast () https://msdn.microsoft.com/en-us/library/bb341406(v=vs.110).aspx – 0xFF

+0

@fhlamarche: Нет, поскольку Мне нужно, чтобы проекция произошла внутри механизма базы данных, а не на стороне клиента. – davenewza

+0

Не могли бы вы дать нам образец DataSet и ожидаемый результат? – Complexity

ответ

1

Я нашел способ выполнить отображение вы хотите:

collection 
    .Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, new[] { "c" })) 
    .Project(Builders<MyType>.Projection.Exclude(c => c.Documents)) 
    .As<MySubType>() 
    .ToList(); 

Но сначала вы должны зарегистрировать отображение для SubType с игнорируя дополнительный элемент. Я не понимаю его на 100%, кажется, ошибка в драйвере, он не получает Documents от mongo, но знает, что у MyType есть такое свойство. Обратите внимание, что вы должны зарегистрировать сопоставление классов, до, вы сначала создаете коллекцию этого типа.

if (!BsonClassMap.IsClassMapRegistered(typeof(MySubType))) 
{ 
    BsonClassMap.RegisterClassMap<MySubType>(cm => 
    { 
     cm.AutoMap(); 
     cm.SetIgnoreExtraElements(true); 
    }); 
} 

Я сделал это с данными выборки:

var toInsert = new List<MyType> 
{ 
    new MyType {Id = 1, Name = "bla", Documents =new List<string> {"a", "b", "v"}}, 
    new MyType {Id = 2, Name = "ada", Documents =new List<string> {"c", "d", "r"}}, 
}; 

И может получить ожидаемый результат:

collection 
    .Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, new[] { "c" })) 
    .Project(Builders<MyType>.Projection.Exclude(c => c.Documents)) 
    .As<MySubType>() 
    .ToList() 
    .Dump(); 

enter image description here

+0

Спасибо. Кроме того, я написал метод расширения, чтобы исключить все соответствующие свойства неявно (используя отражение). – davenewza

 Смежные вопросы

  • Нет связанных вопросов^_^