流利的NHibernate - 如何使用鉴别器创建每个子类的映射? [英] Fluent NHibernate - how to create table-per-subclass mapping using a discriminator?

查看:139
本文介绍了流利的NHibernate - 如何使用鉴别器创建每个子类的映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过很多关于SO和google的关于nhibernate / fluent-nhibernate中的子类映射的问题,并没有设法找到与我相同问题的任何人。我已经按照fluent-nhibernate维基(http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses)的基本说明进行了操作,但这并没有起到什么作用。



我有一个名为操作的基本实体 - 它有一个基表与它关联,然后我有子表UnpaidCheque,退款等 - 每个这些子表的主键是一个外键,OperationId(PK)从当我创建一个持久化规范并试图验证我的映射时,它试图将所有列保存到操作表中,而不是保存到操作中表,然后将Unpaid Check的特定列保存到UnpaidCheque表中。

错误是:

 无法插入:[UnpaidChe] (SQL:INSERT INTO Account.Operation(PaymentId,Amount,UnpaidOn,UnpaidByUserId,OperationType)VALUES(?,?,?,?,'U');选择SCOPE_IDENTITY()] 
----> System.Data.SqlClient.SqlException:无效的列名称UnpaidOn。
列名称'UnpaidByUserId'无效。

正如你所看到的,它试图保存UnpaidByUserId和UnpaidOn列中的值-table / class,而不是base。



另一方面,它试图在操作类型列中插入'U'的事实表明它似乎是为类类型设置正确的描述符值。我指定操作类型的唯一地方是在类映射的DiscriminatorValue()调用中,我没有明确地在其他地方设置它。



类层次结构如下:

  public class Operation 
{
public virtual long OperationId {get;组; }
公共虚拟字符串OperationType {get;组; }
public virtual long? PaymentId {get;组; }
public virtual decimal Amount {get;组; }
}

public class UnpaidCheque:Operation
{
public virtual DateTime UnpaidOn {get;组; }
public virtual long UnpaidByUserId {get;组;




$ b $ p



  public class OperationMap:ClassMap< Operation> 
{
public OperationMap()
{
Schema(Account);
表(操作);
LazyLoad();
Id(_ => _.OperationId).Column(OperationId)。GeneratedBy.Identity();
Map(_ => _.PaymentId).Column(PaymentId)。Nullable();
Map(_ => _.Amount).Column(Amount)。Not.Nullable();

DiscriminateSubClassesOnColumn(OperationType);
}
}
public class UnpaidChequeMap:SubclassMap< UnpaidCheque>
{
public UnpaidChequeMap()
{
Schema(Account);
表(UnpaidCheque);
LazyLoad();
DiscriminatorValue(U);
KeyColumn(OperationId);
Map(_ => _.UnpaidOn).Column(UnpaidOn)。Not.Nullable();
Map(_ => _.UnpaidByUserId).Column(UnpaidByUserId)。Not.Nullable();


$ / code $ / pre

我看不到任何我做过的不同的事情从除了在子类映射中添加KeyColumn()之外的例子,但是我没有得到相同的错误消息。任何人都可以摆脱我已经错过了什么,或者如果我正在努力实现是由nhibernate支持?据我所知,应该是这样的。



在此先感谢!

解决方案

Descriminators仅适用于所有子类都存储在数据库的同一个表中的映射。 b
$ b

删除行:

  DiscriminateSubClassesOnColumn(OperationType); 

来自父映射和$ / b>

  DiscriminatorValue( U); 

从子映射中解脱出来,然后从数据库中移除列。


I've looked at a lot of questions on SO and google regarding sub-class mappings in nhibernate / fluent-nhibernate and not managed to find anyone with the same problem as me. I've followed the basic instructions from the fluent-nhibernate wiki (http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses) but this hasn't helped.

I have a base entity called Operation - which has a base table associated with it, I then have sub-tables UnpaidCheque, Refund etc - the primary key for each of these sub-tables is a foreign-key, the OperationId (PK) from the Operation table.

When I create a persistence specification and try to verify my mappings it is trying to save all the columns to the Operation table, rather than saving to the Operation table and then saving the specific columns of Unpaid Cheque to the UnpaidCheque table.

The error is:

could not insert: [UnpaidCheque][SQL: INSERT INTO Account.Operation (PaymentId, Amount, UnpaidOn, UnpaidByUserId, OperationType) VALUES (?, ?, ?, ?, 'U'); select SCOPE_IDENTITY()]
  ----> System.Data.SqlClient.SqlException : Invalid column name 'UnpaidOn'.
Invalid column name 'UnpaidByUserId'.

As you can see, it's trying to save values in UnpaidByUserId and UnpaidOn columns which are members of the sub-table/class and not the base.

On the plus side, the fact it's trying to insert 'U' into the operationtype column indicates to me that it seems to be setting the right descriminator value for the class type. The only place I have specified the operationtype is in the DiscriminatorValue() call in the class map, I am not explicitly setting it anywhere else.

The class hierarchy is as follows:

public class Operation
    {
        public virtual long OperationId { get; set; }
        public virtual string OperationType { get; set; }
        public virtual long? PaymentId { get; set; }
        public virtual decimal Amount { get; set; }
    }

public class UnpaidCheque : Operation
    {
        public virtual DateTime UnpaidOn { get; set; }
        public virtual long UnpaidByUserId { get; set; }
    }

The class mappings are:

public class OperationMap : ClassMap<Operation>
    {
        public OperationMap()
        {
            Schema("Account");
            Table("Operation");
            LazyLoad();
            Id(_ => _.OperationId).Column("OperationId").GeneratedBy.Identity();
            Map(_ => _.PaymentId).Column("PaymentId").Nullable();
            Map(_ => _.Amount).Column("Amount").Not.Nullable();

            DiscriminateSubClassesOnColumn("OperationType");
        }
    }
public class UnpaidChequeMap : SubclassMap<UnpaidCheque>
{
    public UnpaidChequeMap()
        {
            Schema("Account");
            Table("UnpaidCheque");
            LazyLoad();
            DiscriminatorValue("U");
            KeyColumn("OperationId");
            Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable();
            Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable();
        }
}

I can't see anything I've done differently from the example other than the addition of the KeyColumn() in the subclass map however I get the same error message without that as well. Can anyone shed any light on what I have missed or if what I am trying to achieve is supported by nhibernate? As far as I can tell it should be.

Thanks in advance!

解决方案

We found the solution:

Descriminators are only for mappings where all the sub-classes are stored in the same table in the database.

Removing the lines:

DiscriminateSubClassesOnColumn("OperationType");

from the parent mapping and

DiscriminatorValue("U");

from the child mapping, and subsequently removing the column from the database solved the issue.

这篇关于流利的NHibernate - 如何使用鉴别器创建每个子类的映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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