简体   繁体   English

许多人加入Fluent NHibernate的自我问题

[英]Issue with self-many to many join in Fluent NHibernate

I am a complete Fluent Newbie and while I have found a lot on the 'net about Many-to-many joins, I havent found much in my current scenario. 我是一个完全的流利的新手,虽然我在网上找到了很多关于多对多联接的信息,但在目前的情况下我还没有发现太多。

Note: Ok, this may be rubbish design and I may be better off making seperate tables, insults about the design are appreciated :) 注意:好的,这可能是垃圾设计,我最好制作单独的桌子,对设计的侮辱是可以理解的:)

I have a table like so: 我有这样的一张桌子:

数据库

And classes such: 和这样的类:

[Serializable]
public class Transaction : Entity
{
    [DomainSignatureAttribute]
    public virtual long TransactionId { get; protected internal set; }
    public virtual long AccountId { get; set; }
    protected internal virtual short TransactionTypeId { get; set; }
    protected internal virtual short TransactionStatusId { get; set; }
    public virtual DateTime DateCreated { get; set; }
    public virtual DateTime DateEffective { get; set; }
    public virtual Decimal Amount { get; set; }

    public virtual IList<TransactionLink> ChildTransactions { get; set; }
    public virtual IList<TransactionLink> ParentTransactions { get; set; }

    public Transaction()
    {
        ChildTransactions = new List<TransactionLink>();
        ParentTransactions = new List<TransactionLink>();
    }

    /// <summary>
    /// Use this to add a payment to a charge to pay it off, or to add a refund on a payment to un-pay it
    /// </summary>
    /// <param name="inTransaction"></param>
    /// <param name="inAmount"></param>
    public virtual void AddChildTransaction(Transaction inTransaction, Decimal inAmount)
    {
        TransactionLink link = new TransactionLink()
                                            {
                                                TransactionParent = this,
                                                TransactionChild = inTransaction,
                                                Amount = inAmount
                                            };

        if (!ChildTransactions.Contains(link))
            ChildTransactions.Add(link);

        if (!inTransaction.ParentTransactions.Contains(link))
            inTransaction.ParentTransactions.Add(link);
    }

    /// <summary>
    /// You probably shouldnt be using this.
    /// </summary>
    /// <param name="inTransaction"></param>
    /// <param name="inAmount"></param>
    public virtual void AddParentTransaction(Transaction inTransaction, Decimal inAmount)
    {
        TransactionLink link = new TransactionLink()
                                            {
                                                TransactionChild = this,
                                                TransactionParent = inTransaction,
                                                Amount = inAmount
                                            };

        if (!inTransaction.ChildTransactions.Contains(link))
            inTransaction.ChildTransactions.Add(link);

        if (!ParentTransactions.Contains(link))
            ParentTransactions.Add(link);
    }
}

And

[Serializable]
public class TransactionLink : Entity
{
    public virtual Int64 TransactionIdParent { get; protected internal set; }
    public virtual Transaction TransactionParent { get; set; }

    public virtual Int64 TransactionIdChild { get; set; }
    public virtual Transaction TransactionChild { get; protected internal set; }

    public virtual DateTime LastModifiedOn { get; set; }
    public virtual Decimal Amount { get; set; }

    #region Override comparison - as this is a composite key we need to custom roll our comparison operators

    #endregion
}

Maps: 地图:

public TransactionMap()
    {
        Id(x => x.TransactionId);

        Map(x => x.AccountId);
        Map(x => x.TransactionTypeId);
        Map(x => x.TransactionStatusId);
        Map(x => x.DateCreated);
        Map(x => x.DateEffective);
        Map(x => x.Amount);
        HasMany(x => x.ParentTransactions).Cascade.None().KeyColumn("TransactionIdParent").LazyLoad();
        HasMany(x => x.ChildTransactions).Cascade.All().KeyColumn("TransactionIdChild").LazyLoad();
    }

and

public TransactionLinkMap()
    {
        CompositeId()
            .KeyProperty(x => x.TransactionIdParent, "TransactionIdParent")
            .KeyProperty(x => x.TransactionIdChild, "TransactionIdChild");

        References(x => x.TransactionParent).Column("TransactionIdParent").Cascade.SaveUpdate().LazyLoad();
        References(x => x.TransactionChild).Column("TransactionIdChild").Cascade.All().LazyLoad();

        Version(x => x.LastModifiedOn);
        Map(x => x.Amount);
    }

I am tweaking things around and getting all kinds of errors from nHibernate - someone please tell me what is the best way to go about this?? 我正在进行调整,并从nHibernate中获取各种错误-有人请告诉我解决此问题的最佳方法是什么?

Gah, problem found - after Jonas pointed to the other setup I figured the issue must be with a composite key - the answer? Gah,发现了问题-在乔纳斯(Jonas)指出其他设置之后,我认为问题必须出在复合键上-答案是? Don't use a composite key! 不要使用组合键!

Even with the Version() property set nHibernate saw all Transient objects to be the same, thus was messing up when I was trying to add 3 Transactions in one hit. 即使设置了Version()属性,nHibernate仍然看到所有Transient对象都是相同的,因此当我试图在一击中添加3个Transaction时,情况还是很混乱。

The solution to this problem, if anyone else hits the same thing, is to add an auto-increment key to the many to many table and use that as a key within nHibernate, which makes it much easier for nHibernate to differenciate between Transient objects! 如果有人遇到同样的问题,此问题的解决方案是在多对多表中添加一个自动递增键,并将其用作nHibernate中的键,这使nHibernate轻松区分瞬态对象!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM