1

複数の HasMany リレーションシップを持つオブジェクトを保存しようとすると、「オブジェクトは保存されていない一時インスタンスを参照しています - フラッシュする前に一時インスタンスを保存してください」という例外が発生します。

以下は、単純化されたクラス、対応するマッピング、および「アプリケーション」コードです。

「アプリケーション コード」セクションは、私がやりたいことを示しています。経費レポートと作業時間を請求書に追加し、請求書を保存します。

ただし、例外は GetTimeWorked() で発生します。順序を逆にすると (経費報告の前に作業時間を追加する)、GetExpenseReports() でエラーが発生します。

経費報告書を追加した後に請求書を保存し、勤務時間を追加した後に再度保存すると、問題なく動作します。ただし、この保存はトランザクションである必要があります。経費レポートと作業時間は一緒に保存する必要があります。

私はこの例外について多くのことを読みましたが、私が試したことは何もありません。私が読んだ状況は、これとは少し異なるようです。これはマッピングの問題であると推測しており、別のマッピング (HasMany 側で Cascade を使用) を試しましたが、途方に暮れています。

ここで何が起こっているのか、どうすれば解決できますか?

ありがとう!

// Classes
public class TimeWorked {
    public virtual long Id { get; private set; }
    public virtual float Hours { get; set; }
    public virtual Invoice Invoice { get; set; }
}

public class ExpenseReport {
    public virtual long Id { get; set; }
    public virtual IList<Expense> Expenses { get; set; }                
    public virtual Invoice Invoice { get; set; }
}

public class Invoice {
    public virtual long Id { get; set; }
    public virtual IList<ExpenseReport> ExpenseReports { get; set; }
    public virtual IList<TimeWorked> BilledTime { get; set; }

    public virtual void AddExpenseReport(List<ExpenseReport> expenseReports)
    {
        foreach (ExpenseReport er in expenseReports)
        {
            ExpenseReports.Add(er);
            er.Invoice = this;
        }
    }

    public virtual void AddTimeWorked(List<TimeWorked> timeWorked)
    {
        foreach (TimeWorked tw in timeWorked)
        {
            BilledTime.Add(tw);
            tw.Invoice = this;
         }
    }       
}

// Mapping
public class TimeWorkedMapping : ClassMap<TimeWorked>
{
    public TimeWorkedMapping()
    {
        Id(x => x.Id);
        References(x => x.Invoice);
    }
}

public class ExpenseReportMapping : ClassMap<ExpenseReport>
{
    public ExpenseReportMapping()
    {
        // Primary Key
        Id(x => x.Id);
        HasMany(x => x.Expenses).Cascade.AllDeleteOrphan();
            References(x => x.Invoice);
    }
}

public class InvoiceMapping : ClassMap<Invoice>
{
    public InvoiceMapping()
    {
        Id(x => x.Id);      
        HasMany(x => x.ExpenseReports).Inverse();
        HasMany(x => x.BilledTime).Inverse();
    }
}


// Application Code

public class MyPage
{
    // Do stuff...
    Invoice invoice = new Invoice();

    // Add the expense reports                       
    List<ExpenseReport> erList = GetExpenseReports();
    invoice.AddExpenseReport(erList);

    // Add billable time
    List<TimeWorked> twList = GetTimeWorked();     <<== Exception occurs in here
    invoice.AddTimeWorked(twList);

    // Save invoice
    Save(invoice);

} 
4

2 に答える 2

1

新しい請求書を作成する前にリストを取得してください。デフォルトの請求書 ID に問題がある可能性があります。

List<TimeWorked> twList = GetTimeWorked();
List<ExpenseReport> erList = GetExpenseReports();
Invoice invoice = new Invoice();

// Add the expense reports                       
invoice.AddExpenseReport(erList);

// Add billable time  
invoice.AddTimeWorked(twList);

// Save invoice
Save(invoice);
于 2012-01-26T07:11:54.110 に答える
0

session.Flushmode == FlushMode.Commit を設定すると役立ちます。請求書を推測GetExpenses()してGetTimeWorked()参照すると、フラッシュが発生して正しいデータが取得されます

于 2012-01-26T15:43:40.133 に答える