Как использовать внутреннее соединение в Fluent NHibernate для извлечения одного свойства из правой таблицы - PullRequest
0 голосов
/ 16 октября 2019

У меня есть запрос, который выбирает каждое свойство из одной таблицы, однако запрос должен извлечь одно дополнительное свойство из другой таблицы.

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

Это модель запрашиваемой таблицы:

public class Car
{
    public long Id;
    public long SellerId;
    public string Name;
    public string SellerName;
}

Тем не менее, свойство SellerName не сопоставляется, поскольку это свойство относится к другой модели:

public class Seller
{
    public long Id;
    public string SellerName;
}

В настоящее время сопоставление классов автомобилей выполняется следующим образом:

Property(x => x.Id);
Property(x => x.SellerId);
Property(x => x.Name);

Это создастмодель, подобная этой:

Car Table
|------------------------------------------------|
|Id         | SellerId      | Name              |
|1          | 1             | Car Number one    |
|------------------------------------------------|

Employee Table
|---------------------------|
|Id         | Name          |
|1          | John Doe      |
|---------------------------|

Используя простой запрос, я могу легко использовать внутреннее объединение для сбора данных автомобиля с соответствующим именем сотрудника:

select c.*, p.Name from Car c
inner join Employee e on c.Id = e.EmployeeId

Я уже пробовалэтот запрос:

var query = from car in session.Query<Car>() 
    join employee in session.Query<Employee>() on car.SellerId equals employee.Id
    select new Car
    {
        Id = car.Id,
        SellerId = car.SellerId,
        Name = car.Name,
        ClientName = employee.ClientName
    };

Но на самом деле это создает два запроса в базе данных, один для таблицы клиента, а другой для сотрудника. И это не использует Linq, что также является обязательным требованием.

Ответы [ 2 ]

0 голосов
/ 16 октября 2019

Во-первых, вы должны использовать virtual свойства для поведения NHibernate. Вы можете отобразить отношение в вашей модели, например,

public class Car
{
    public virtual long Id { get; set; }    
    public virtual string Name { get; set; }
    public virtual long SellerId { get; set; }
    public virtual Employee Seller { get; set; }
}

И вашу карту,

public class CarMap : ClassMap<Car>
{
    public CarMap()
    {
        // map other properties...

        // You could map the the SellerId to be easy to access here (just readonly, use the reference to persist)
        Map(x => x.SellerId).Column("SellerId").Not.Nullable().ReadOnly();

        References(x => x.Seller).Column("SellerId");
    }
}

Если у вас есть правильная модель и вы используете Linq, вы можетеиспользуйте метод Fetch из пространства имен NHibernate.Linq, и это заставит вас объединиться, избегая отложенной загрузки. Для образца:

var data = session.Query<Car>()
                  .Fetch(x => x.Seller)
                  .ToList();
0 голосов
/ 16 октября 2019

Вам не нужно указывать все свойства объекта в select. Просто используйте анонимный объект, чтобы получить и сущность, и дополнительное свойство. Следующий запрос должен быть выполнен за одну поездку в дб:

var query = from car in session.Query<Car>() 
    join employee in session.Query<Employee>() on car.SellerId equals employee.Id
    select new 
    {
        Car = car,
        ClientName = employee.ClientName
    };

И выполнить все необходимые преобразования после выполнения запроса (установите unmapped car.SellerName в ClientName), как кажется, используя сопоставленную сущность с присваиваниями вОператор select сбивает с толку NHibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...