Fluent NHibernate присоединяется к одному столбцу из другой таблицы

Я использую Fluent NHibernate и имею две таблицы;

Клиент [ID, Имя, ЯзыкID]

Языки [ID, Описание]

У меня есть объект Customer со следующими свойствами; ID, имя, язык, язык

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

Я попытался использовать Join, но я не могу заставить его использовать поле LanguageID в таблице клиентов, чтобы присоединиться к таблице "Языки" - он все еще хочет использовать "ID".

Мое отображение выглядит следующим образом:

        Table("Customers");
        Not.LazyLoad();
        Id(c => c.ID).GeneratedBy.Assigned();
        Map(c => c.Name);
        Map(c => c.LanguageID);
        Join("Languages", join =>
        {
            join.KeyColumn("ID");
            join.Map(prop => prop.Language).Column("Description");
        });

Ответы

Ответ 1

Я раньше не использовал Join, но, думаю, вам нужен внешний ключ от клиента в вашем сопоставлении:

    Table("ScriptActivities");
    Not.LazyLoad();
    Id(c => c.ID).GeneratedBy.Assigned();
    Map(c => c.Name);
    Map(c => c.LanguageID);
    Join("Languages", join =>
    {
        join.KeyColumn("LanguageID");
        join.Map(prop => prop.Language).Column("Description");
    });

Отредактировано для добавления: лучший пример, который я смог найти при сопоставлении соединения, - блог Айенде. Из этого примера мне кажется, что соединение ожидает, что идентификатор сопоставленного объекта будет внешним ключом в объединенной таблице. Ваша схема имеет объединенный идентификатор таблицы как FK в сопоставленном объекте, поэтому соединение не будет работать. Я предлагаю создать представление, объединяющее клиент и язык и отображающее его.

Ответ 2

Я думаю, вы можете создать Entity для языка. Позже в Entity для Customer есть ссылка на этот Entity.

public class Customer
{
    public virtual int Id { get; set; }
    public virtual string Name{ get; set; }
    public virtual Language Language { get; set; }
}

Затем в CutomerMap вы должны сделать:

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        References(x => x.Language);
    }
}

Позже, когда вы вызываете своих клиентов, вы можете решить показать "instance.Language.Description"

Например, в MVC в контроллере вы можете:

 public ActionResult Index()
    {
        using (ISession session = NHibernateHelper.OpenSession())
        {
            var customers = session.Query<Customer>().Fetch(x => x.Language).ToList();
            return View(customers);
        }
    }

И в представлении:

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Name)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Language.Description)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })
    </td>
</tr>
}

Надеюсь, что это поможет.