Драйвер mongodb-csharp - как сохранить свойство как ссылку, а не как встроенное? - PullRequest
11 голосов
/ 04 октября 2010

Мы делаем небольшой всплеск в базе данных Mongo для нашего проекта C # .NET, чтобы понять, подходит ли он нам, и я столкнулся с небольшой проблемой с драйвером mongodb-csharp от samus, в которой я не уверен как реализовать.

Учитывая следующую упрощенную модель:

public class Campaign
{        
    public string Name { get; set; }
    public IEnumerable<Placement> Placements { get; set; }
}

public class Placement
{
    public string Name { get; set; }

    //this should be a reference rather than included in the collection
    public Site Site { get; set; }
}

//this should be its own collection, and not embedded anywhere
public class Site
{
    public string Name { get; set; }
}

Мы пытаемся выяснить, как в приведенных выше комментариях, как сохранить сайт как ссылочный тип, а не встроенный в место размещения. Сайт - это собственная коллекция верхнего уровня, которая изменяется независимо от каждой кампании.

В идеале я хотел бы сделать это, используя MongoConfigurationBuilder, а не изменять мои POCO. Я просто не могу найти какую-либо документацию о том, как это делается.

Я надеялся, что это будет так же просто, как:

var config = new MongoConfigurationBuilder();

config.Mapping(mapping =>
{
    //maybe some more configuration here?
    mapping.Map<Site>();
    mapping.Map<Campaign>();
});

Но это все еще встраивание сайтов, когда я использую следующий код:

var db = mongo.GetDatabase("foo");

var campaignCollection = db.GetCollection<Campaign>();
var siteCollection = db.GetCollection<Site>();

var firstSite = new Site{Name = "first site"};
var secondSite = new Site{Name = "second site"};

var firstCampaign = new Campaign
{
    Name = "first campaign",
    Placements = new List<Placement>
    {
        new Placement{Name = "first placement", Site = firstSite},
        new Placement{Name = "second placement", Site = secondSite}
    }
};

siteCollection.Save(firstSite);
siteCollection.Save(secondSite);

campaignCollection.Save(firstCampaign);

Это дает нам:

{ "_id" : ObjectId("4ca9f1db54730000000010cb"), 
  "Name" : "first campaign", 
  "Placements" : [
    {
      "Name" : "first placement",
      "Site" : { "Name" : "first site" }
    },
    {
      "Name" : "second placement",
      "Site" : { "Name" : "second site" }
    }
  ]}

{ "_id" : ObjectId("4ca9f1db54730000000010c9"), "Name" : "first site" }
{ "_id" : ObjectId("4ca9f1db54730000000010ca"), "Name" : "second site" }

В то время как мы хотим что-то похожее на:

{ "_id" : ObjectId("4ca9f1db54730000000010cb"), 
  "Name" : "first campaign", 
  "Placements" : [
    {
      "Name" : "first placement",
      "Site" : ObjectId("4ca9f1db54730000000010c9")
    },
    {
      "Name" : "second placement",
      "Site" : ObjectId("4ca9f1db54730000000010ca")
    }
  ]}

{ "_id" : ObjectId("4ca9f1db54730000000010c9"), "Name" : "first site" }
{ "_id" : ObjectId("4ca9f1db54730000000010ca"), "Name" : "second site" }

Я не уверен, что это именно тот документ, к которому мы пришли бы, но вы поняли.

Мне кажется, что я упускаю что-то очевидное, но без лучшей документации по этому аспекту драйвера я вроде как стреляю в темноте. Я даже просмотрел тесты в источнике и не смог понять.

Кто-нибудь знает, как это сделать? Возможно ли это?

1 Ответ

9 голосов
/ 05 октября 2010

Для этого вы должны использовать DBRef .

Чтобы сделать это в c #, вы должны изменить класс своей кампании следующим образом

public class Campaign
{        
    public string Name { get; set; }
    public List<DBRef> Placements { get; set; }
}

И вставить справочный документ, как это

List<DBRef> refList = new List<DBRef>() {firstSite,secondSite };


var firstCampaign = new Campaign
{
    Name = "first campaign",
    Placements = refList
};

campaignCollection.Save(firstCampaign);

Я не тестировал код, но это дает подсказку, как этого добиться.

...