2017-01-09 16 views
1

のために私は、データベースを文書化するために近づいていると私は、文書の関係をマッピングする方法が少し混乱していますモデル1は、より良いパフォーマンス

public Car Get(int id) 
    { 
     Car car = null; 
     using (IDocumentSession session = store.OpenSession()) 
     { 
      car = session.Include<Car, Person>(x => x.PersonId).Load<Car>(id); 
      bool isLoaded = session.Advanced.IsLoaded("people/" + car.PersonId); // true! 
     } 
     return car; 
    } 

に従うと、それはすべて大丈夫だと私はデシベルを照会することができます。この方法では、たとえば車は、クライアントが一つだけ要求を行うが、私は、人を持っていると私は照会することができますどのようにすべての彼の車を表示したい場合dbはちょうどリクエストを行うには? 私は彼の車を参考にList<int> CarsPersonに入れてモデルを修正しなければならないと思います。 Carsは他のドキュメントから参照できるため、CarsPersonドキュメントに埋め込むことは望ましくありません。

ありがとうございました。

答えて

3

インデックスからCarsコレクションを索引付けし、すべての車をロードできます。

インデックスは次のようになります。

public class CarIndex : AbstractIndexCreationTask<Car, CarView> 
{ 
    public CarIndex() 
    { 
     Map = cars => from car in cars 
         select new 
         { 
          car.Id, 
          car.Name, 
          car.PersonId, 
         }; 
    } 
} 

カービュークラスはCarクラスと同じですが、より良いインデックスニーズに合わせて変更することができます。

public class CarView 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int PersonId { get; set; } 
} 

あなたはそれを使用できるようになる前に、インデックスを実行する必要があります:

new CarIndex().Execute(store); 

がある人のための車のロード次のようになります。

using (IDocumentSession session = store.OpenSession()) 
{ 
    session.Store(new Person { Id = 1, Name = "A", Surname = "A" }); 
    session.Store(new Car { Id = 1, Name = "A", PersonId = 1 }); 
    session.Store(new Car { Id = 2, Name = "B", PersonId = 1 }); 
    session.Store(new Car { Id = 3, Name = "C", PersonId = 2 }); 
    session.SaveChanges(); 
} 

WaitForIndexing(store); // from RavenTestBase 

using (IDocumentSession session = store.OpenSession()) 
{ 
    var resultsForId1 = session 
     .Query<CarView, CarIndex>() 
     .ProjectFromIndexFieldsInto<CarView>() 
     .Where(x => x.PersonId == 1); 
    Assert.Equal(2, resultsForId1.Count()); 
    var resultsForId2 = session 
     .Query<CarView, CarIndex>() 
     .ProjectFromIndexFieldsInto<CarView>() 
     .Where(x => x.PersonId == 2); 
    Assert.Equal(1, resultsForId2.Count()); 
} 

あなたの場合1人のデータベース要求で人とその車をロードしたい場合は、遅延読み込みを使用してください:

var resultsForId1 = session 
    .Query<CarView, CarIndex>() 
    .ProjectFromIndexFieldsInto<CarView>() 
    .Where(x => x.PersonId == 1).Lazily(); 
var person = session.Advanced.Lazily.Load<Person>(1); 

var personValue = person.Value; 
var resultsValue = resultsForId1.Value; 

完全なテスト(のxUnitとRavenDB.Tests.Helpers nugetsを必要とします):

using (IDocumentSession session = store.OpenSession()) 
{ 
    var carsForOne = session.Query<Car>() 
      .Include(x=>x.PersonId) 
      .Where(x=>x.PersonId == "people/1") 
      .ToList(); 

    var person = session.Load<Person>("people/1"); 
} 

このメイクだけで、単一のDB要求:

using Raven.Client; 
using Raven.Client.Indexes; 
using Raven.Tests.Helpers; 
using System; 
using System.Linq; 
using Xunit; 

namespace SO41547501Answer 
{ 
    public class SO41547501 : RavenTestBase 
    { 
     [Fact] 
     public void SO41547501Test() 
     { 
      using (var server = GetNewServer()) 
      using (var store = NewRemoteDocumentStore(ravenDbServer: server)) 
      { 
       new CarIndex().Execute(store); 

       using (IDocumentSession session = store.OpenSession()) 
       { 
        session.Store(new Person { Id = 1, Name = "A", Surname = "A" }); 
        session.Store(new Car { Id = 1, Name = "A", PersonId = 1 }); 
        session.Store(new Car { Id = 2, Name = "B", PersonId = 1 }); 
        session.Store(new Car { Id = 3, Name = "C", PersonId = 2 }); 
        session.SaveChanges(); 
       } 

       WaitForAllRequestsToComplete(server); 
       WaitForIndexing(store); 

       using (IDocumentSession session = store.OpenSession()) 
       { 
        var resultsForId1 = session 
         .Query<CarView, CarIndex>() 
         .ProjectFromIndexFieldsInto<CarView>() 
         .Where(x => x.PersonId == 1); 
        Assert.Equal(2, resultsForId1.Count()); 
        var resultsForId2 = session 
         .Query<CarView, CarIndex>() 
         .ProjectFromIndexFieldsInto<CarView>() 
         .Where(x => x.PersonId == 2); 
        Assert.Equal(1, resultsForId2.Count()); 
       } 

       using (IDocumentSession session = store.OpenSession()) 
       { 
        server.Server.ResetNumberOfRequests(); 
        var resultsForId1 = session 
         .Query<CarView, CarIndex>() 
         .ProjectFromIndexFieldsInto<CarView>() 
         .Where(x => x.PersonId == 1).Lazily(); 
        var person = session.Advanced.Lazily.Load<Person>(1); 

        var personValue = person.Value; 
        var resultsValue = resultsForId1.Value; 
        Assert.Equal("A", personValue.Name); // person data loaded 
        Assert.Equal("A", resultsValue.First().Name); // cars data loaded 
        Assert.Equal(1, server.Server.NumberOfRequests); // only one request sent to the server 
       } 
      } 
     } 
    } 

    public class CarIndex : AbstractIndexCreationTask<Car, CarView> 
    { 
     public CarIndex() 
     { 
      Map = cars => from car in cars 
          select new 
          { 
           car.Id, 
           car.Name, 
           car.PersonId, 
          }; 
     } 
    } 

    public class Person 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public string Surname { get; set; } 
     public DateTime? BirthDate { get; set; } 
    } 

    public class Car 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public int PersonId { get; set; } 
    } 

    public class CarView 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public int PersonId { get; set; } 
    } 
} 
2

あなたはこのようにそれを行うことができます。

関連する問題