如何将NHibernate与分布在多个表上的实体一起使用? [英] How to use NHibernate with entity spread over multiple tables?

查看:121
本文介绍了如何将NHibernate与分布在多个表上的实体一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个预先存在的表,使用一种开放模式.我有一个Item表,各种实体都归类为Items,然后将属性存储在Item属性表中.单个实体类型可能具有存储在多个表中的字段.我们用视图公开实体.因此,大多数实体都对应于一个视图,然后当我们插入/更新时,我们必须系统地更新表或使用存储过程.

I have pre-existing tables, using a kind of open schema. I have an Item table, and various entities are classified as Items, and then have properties stored in Item property tables. A single entity type may have fields stored in multiple tables. We expose entities with views. So, most entities correspond to a view, and then when we insert/update we have to systematically update the tables or use stored procedures.

我正在尝试确定NHibernate是否将从定制仓库(遵循工厂模式)中获得任何收益.现在,我很难让NHibernate处理这种数据库模式.从我的角度来看,我们要么必须完全重构数据库以遵循NHibernate的约定,要么完全重构或以某种方式重构实体.

I'm trying to determine if NHibernate will gain us anything over our custom-built repositories (which follow a factory pattern). Right now, I'm seeing great difficulty in getting NHibernate to deal with this kind of database schema. The way I see it, we'd either have to completely refactor our database to follow NHibernate's conventions, or completely refactor or entities somehow.

除了在最简单的示例中所涉及的数据库或多或少都遵循NHibernate的约定外,我在文档中没有看到太多有关如何执行此操作的信息.

I'm not seeing much in the documentation about how to do this, except for the very simplest of examples that involve databases that more or less follow NHibernate's conventions.

这是一个代表性的数据库图.我们拥有Episode作为实体,可以从Item,IP_Episode,IP_EpisodeBroadcastInfo,IP_Show等中提取信息,以构建其所需的所有字段.

Here's a representative database diagram. We have Episode as an entity that pulls info from Item, IP_Episode, IP_EpisodeBroadcastInfo, IP_Show, etc. to build all the fields that it needs.

推荐答案

您提到了约定.那是Fluent NHibernate的概念,是的,您正在做的事情与Fluent NHibernate的现有约定不完全一致.但是,这完全在NHibernate的能力范围内. NHibernate擅长于将其映射到各种不同的数据库模式.不要对Fluent NHibernate希望您采取的方式感到束缚.我并不是说不要使用Fluent NHibernate.如果您在数据库架构中保持一致和合理,则可以编写自己的约定以进行匹配.

You mention conventions. That is a Fluent NHibernate concept, and yes, what you are doing is not exactly in line with Fluent NHibernate's existing conventions. However, it is well within NHibernate's capabilities. NHibernate excels at being able to be mapped to all sorts of different database schemas. Don't feel constrained to the way Fluent NHibernate wants you to go. I'm not saying don't use Fluent NHibernate. If you are consistent and reasonable in your database schema, you can write your own conventions to match.

为了说明NHibernate的灵活性,我们假设我们具有类似于以下内容的表结构:

To illustate NHibernate's flexibility, let's assume we have a table structure similar to this:

create table Episode (
    Id int not null primary key,
    NumberInSeries int null
);

create table Show (
    Episode_id int not null primary key,
    Title nvarchar(100) not null,
    foreign key (Episode_id) references Episode (Id)
);

create table Broadcast (
    Episode_id int not null primary key,
    InitialAirDate datetime not null,
    foreign key (Episode_id) references Episode (Id)
);

Episode中的一行对应于Show中的零行或一行,以及Broadcast中的零行或一行.您可以在.NET中以几种不同的方式对这种类型的关系进行建模.以下是通过NHibernate为您提供的各种选项:

One row in Episode corresponds to zero or one rows in Show and zero or one rows in Broadcast. You could model this type of relationship several different ways in .NET. Here are the various options available to you via NHibernate:

public class Episode
{
    public virtual int Id { get; set; }
    public virtual int? NumberInSeries { get; set; }
}

public class Show : Episode
{
    public virtual string Title { get; set; }
}

public class Broadcast : Episode
{
    public virtual DateTime InitialAirDate { get; set; }
}

当您要为不变的关系建模时,请使用此选项.如果情节是表演,则始终是表演.而且,此建模将暗示情节不能同时是表演和广播.我不相信这就是您想要的,但是您可能会发现它在模型的其他地方很有用.

Use this when you want to model a relationship that does not change. If an Episode is a Show, it is always a Show. Also, this modeling would imply that an Episode cannot be both a Show and a Broadcast. I don't believe this is what you want, but you may find it useful elsewhere in your model.

有关更多信息,请参阅...

  • Official documentation on inheritance mapping
  • Ayende's blog post on inheritance mapping
public class Episode
{
    public virtual int Id { get; set; }
    public virtual int? NumberInSeries { get; set; }
    public virtual Show Show { get; set; }
    public virtual Broadcast Broadcast { get; set; }
}

public class Show
{
    public virtual Episode Episode { get; set; }
    public virtual string Title { get; set; }
}

public class Broadcast
{
    public virtual Episode Episode { get; set; }
    public virtual DateTime InitialAirDate { get; set; }
}

这使您可以更好地控制哪些表实际包含与给定情节关联的行,因为例如可以设置episode.Broadcast = null.同时具有给定情节的显示和广播信息也很好.

This gives you more control over which tables actually contain a row associated with a given Episode, because you can set episode.Broadcast = null for example. It's also fine to have both Show and Broadcast information for a given Episode.

有关更多信息,请参阅...

  • one-to-one 上的官方文档
  • Ayende在one-to-one
  • 上的博客文章>
  • Official documentation on one-to-one
  • Ayende's blog post on one-to-one
public class Episode
{
    // These properties come from the Episode table...
    public virtual int Id { get; set; }
    public virtual int? NumberInSeries { get; set; }

    // This one comes from the Show table.
    public virtual string Title { get; set; }

    // This one comes from the Broadcast table.
    public virtual DateTime InitialAirDate { get; set; }
}

这是一种很好的表示数据的简单方法,但是您无法控制是否在Show和Broadcast表中插入行.

This is a nice and simple way to represent the data, but you do not get control over whether on not rows are inserted into the Show and Broadcast tables or not.

有关更多信息,请参阅...

  • Official documentation on join
  • Ayende's blog post on join

自从您说过一个单一的实体类型可能具有存储在多个表中的字段",这听起来像join应该能够处理您当前对事物建模的方式.

Since you said, "A single entity type may have fields stored in multiple tables", it sounds to me like join should be able to handle the way you currently have things modeled.

这篇关于如何将NHibernate与分布在多个表上的实体一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆