如何在 NHibernate 中映射没有标识列的视图?

发布于 2024-12-22 03:21:51 字数 742 浏览 6 评论 0原文

我有一个观点,我只会读取(不会写入)。该视图没有任何唯一键(不是事件组合)。

那么如何在 NHibernate 中映射这个视图而不接触视图呢?我不想向视图添加新列来为我生成唯一的标识。有没有办法映射这个视图并在 NHibernate 端生成标识列?

我可以在我的实体类中生成一个 GUID,例如:

public class MyViewClass
{
    private Guid _id = new Guid();
    public virtual Guid Id { get { return _id; } set { _id = value; } }
}

但是如何才能使映射工作呢?以下代码不起作用:

public class MyViewClass: ClassMapping<MyViewClass>
{
    public MyViewClass()
    {
        Mutable(false);
        Id(x => x.Id, m => m.Generator(Generators.Guid));
    }

} 

它期望在视图中包含 Id 列并抛出:

System.Data.SqlClient.SqlException: Invalid column name 'Id'.

顺便说​​一句,我正在使用 NHibernate 3.2 并通过代码进行映射。

I have a view that I am going to only read from (no writes). This view does not have any unique key (not event composite).

So how can I map this view in NHibernate without touching the view? I do not want to add a new column to the view to generate a unique identity for me. Is there a way to map this view and generate the identity column on the NHibernate side?

I can generate a GUID in my entity class like:

public class MyViewClass
{
    private Guid _id = new Guid();
    public virtual Guid Id { get { return _id; } set { _id = value; } }
}

But how can I make the mapping work? The following code does not work:

public class MyViewClass: ClassMapping<MyViewClass>
{
    public MyViewClass()
    {
        Mutable(false);
        Id(x => x.Id, m => m.Generator(Generators.Guid));
    }

} 

It expects to have the Id column in view and throws:

System.Data.SqlClient.SqlException: Invalid column name 'Id'.

BTW, I am using NHibernate 3.2 and mapping by code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

望笑 2024-12-29 03:21:51

更新:要在 LINQ 中使用它,请将所有列映射为 CompositeId 和 Mutable(false),然后使用默认实现覆盖 Equals 和 GetHashCode。

public class MyViewClass
{
    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

原始答案:

如果您不想插入/更新它,我根本不会映射它

public class MyViewClass
{
    public virtual string Prop1 { get; set; }
    public virtual int Prop2 { get; set; }
}

var viewObjects = session.CreateSQLQuery("SELECT col1 as Prop1, col2 as Prop2 FROM MyView")
    .SetResultTransformer(Transformers.AliasToBean<MyViewClass>())
    .List<MyViewClass>();

Update: to use it in LINQ map all columns as CompositeId and Mutable(false) then override Equals and GetHashCode with default implementation.

public class MyViewClass
{
    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

original answer:

i wouldnt map it at all if you dont want to insert/update it

public class MyViewClass
{
    public virtual string Prop1 { get; set; }
    public virtual int Prop2 { get; set; }
}

var viewObjects = session.CreateSQLQuery("SELECT col1 as Prop1, col2 as Prop2 FROM MyView")
    .SetResultTransformer(Transformers.AliasToBean<MyViewClass>())
    .List<MyViewClass>();
你又不是我 2024-12-29 03:21:51

据我了解,NHibernate 需要一个 Id 列才能将视图映射到实体。因此,要满足此要求,有两种方法:

  1. 添加 Id 列。就我而言,由于我的视图是带有 Id 列的表的摘要,因此我刚刚也在视图定义中添加了 Id 列。
  2. 从映射类中的多个列添加复合 ID。

在映射类中,我还需要添加 SchemaAction(.),否则 NHibernate 会在运行时抱怨它无法将实体映射到表/视图。

映射类将如下所示(选择选项 1 或 2):

public class EntityMap : ClassMapping<Entity> {

  public EntityMap() {
    SchemaAction(NHibernate.Mapping.ByCode.SchemaAction.None);
    Table("NameOfTheView");
    Mutable(false);

    // Option 1
    Id(e => e.Id, map => map.Column("Id"));

    // Option 2
    // NOTE: With ComposedId you need to override Equals() and GetHashCode() in the entity class
    ComposedId(map => {
      map.Property(e => e.Column1);
      map.Property(e => e.Column2);
    });

    // Additional mapping code
  }
}

我也更喜欢将视图映射到实体,因为这样我可以使用 QueryOver 或 Query (LINQ) API 来消除魔术字符串(表/列名称)的使用在普通的 SQL 查询中。

From what I understand, NHibernate needs an Id column to be able to map a view to the entity. So to fulfill this requirement, there are 2 ways:

  1. Add an Id column. In my case, since my view is a summary of a table with an Id column, I just added the Id column also in the view definition.
  2. Add a composite Id from multiple columns in the mapping class.

In the mapping class I also needed to add SchemaAction(.), otherwise NHibernate will complain on runtime that it cannot map the entity to a table/view.

The mapping class would look like this (Either choose option 1 or 2):

public class EntityMap : ClassMapping<Entity> {

  public EntityMap() {
    SchemaAction(NHibernate.Mapping.ByCode.SchemaAction.None);
    Table("NameOfTheView");
    Mutable(false);

    // Option 1
    Id(e => e.Id, map => map.Column("Id"));

    // Option 2
    // NOTE: With ComposedId you need to override Equals() and GetHashCode() in the entity class
    ComposedId(map => {
      map.Property(e => e.Column1);
      map.Property(e => e.Column2);
    });

    // Additional mapping code
  }
}

I also prefer mapping the view to an entity because then I can use QueryOver or Query (LINQ) API to eliminate the use of magic strings (table/column names) in a normal SQL query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文