1

Durandal Web アプリケーションでbreezejs を使用しています。

請求書とその背後にある行を取得するためのコードは次のとおりです。

var getInvoiceById = function (invoiceId, invoiceObservable, forceRemote) {
    // Input: invoiceId: the id of the invoice to retrieve
    // Input: forceRemote: boolean to force the fetch from server
    // Output: invoiceObservable: an observable filled with the invoice

    if (forceRemote)
        queryCacheInvoice = {};

    var query = entityQuery.from('Invoices')
        .where('id', '==', invoiceId)
        .expand("Client, Client.Contacts, Lines")
        .orderBy('Lines.Number');

    var isInCache = queryCacheInvoice[invoiceId];

    if (isInCache && !forceRemote) {
        query = query.using(breeze.FetchStrategy.FromLocalCache);
    } else {
        queryCacheInvoice[invoiceId] = true;
        query = query.using(breeze.FetchStrategy.FromServer);
    }

    return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
        invoiceObservable(data.results[0]);
    }
};

請求書のモデルは次のとおりです。

public class Invoice
{
    [Key]
    public int Id { get; set; }
    public string Number { get; set; }
    public DateTime? Date { get; set; }
    public int? ClientId { get; set; }
    public string Comment { get; set; }
    public double? TotalExclVAT { get; set; }        
    public double? TotalInclVAT { get; set; }
    public double? TotalVAT { get; set; }
    public bool? WithoutVAT { get; set; }

    public virtual List<InvoiceLine> Lines { get; set; }
    public virtual Client Client { get; set; }
}

請求書ごとに、多くの請求書明細があることに注意してください。

public virtual List<InvoiceLine> Lines { get; set; }

InvoiceLine のモデルは次のとおりです。

public class InvoiceLine
{
    [Key]
    public int Id { get; set; }
    [Required]
    public int Number { get; set; }
    [Required]
    public string Description { get; set; }
    public int InvoiceId { get; set; }

    public Invoice Invoice { get; set; }
}

問題: この簡単なクエリを実行すると、以下のエラーが発生しました。

データの取得中にエラーが発生しました。プロパティが見つかりません: タイプの行: 請求書

問題は orderBy 句の周りにあります。Invoice と InvoiceLine の間には 1 対多の関係があるため、この場合は order by を実行できないようです。

私の質問: 請求書の行を番号順に並べ替えるにはどうすればよいですか?

ありがとう。

4

1 に答える 1

3

簡単な答え:できません。これは、Breeze ではなく、Entity Framework の制限です。

EF LINQ クエリで "expand" を使用して含める関連エンティティをフィルター処理、選択、または順序付けすることはできません。

おそらく、クライアント上で関連するエンティティの並べ替え順序を管理することになるでしょう。たとえば、注文明細の表示などです。

また、Breeze ナビゲーション パスによって返されるエンティティのコレクションは順序付けされていないことにも注意してください。Breeze エンティティ ナビゲーション コレクション (Order.LineItems など) を並べ替えようとするとどうなるかわかりませんでした。エンティティに変更を加えたと Breeze が考えてしまうのではないかと心配していました...並べ替えると、コレクションのエンティティを削除してコレクションに追加するように見えるからです。EntityManager実際には何も変更されていないのに、保留中の変更があると思うでしょう。

私は実験を試みましたが、すべてうまくいくようです。Northwindで次のようなことをしました:

  • 顧客の注文を取得しました (「Let's Stop N Shop」)

  • のシーケンスをチェックしましたcust.Orders()。順序付けされていない OrderID があります: [10719, 10735, 10884, 10579]

  • 次のような行を実行しました。cust.Orders().sort(function(left, right){return left.OrderID() < right.OrderID()? -1 : 1})

  • のシーケンスをcust.Orders()再度確認しました。今回はソートされています:[10579、10719、10735、10884]

  • 顧客を確認しましたEntityManager.hasChanges()... まだ偽です (変更なし)。

私は喜んで驚いていることを告白します。これが確実に機能することを確認するには、適切なテストを作成する必要があります。そして、ナビゲーション プロパティへの Knockout バインディングがそれらを並べ替えられた順序で表示することを確認する必要があります。しかし、私はこれまでのところ励まされています。

重要事項:

  1. Breeze はリストをソートしません。新しい注文を追加する場合、または後続のクエリの結果として Breeze が新しい注文をコレクションに追加する場合は、これを行う必要があります。

  2. 並べ替えは、このナビゲーション プロパティにバインドされているすべてのビューに影響します。各ビューにそのコレクション内のエンティティの独自の並べ替えを持たせる場合は、ナビゲーション プロパティ コレクションをシャドウする個別のビュー固有のコレクションを維持する必要があります。

このすべてについて私が間違っている場合は、ビューモデルごとに、必要に応じて並べ替えられた関連エンティティのシャドウ コレクションを管理する必要があります。

6月2日更新

を呼び出して、並べ替え後に配列が変更されたことを KO に知らせる必要があるのではないかと思いましたvalueHasMutated。実験に15分かかりました。そして、それはうまくいくようです。

ASP.NET SPA テンプレートから新しい KO Todo アプリを作成しました (現在、まったく不要な jQuery.UI ライブラリが見つからないという幻の苦情があります)。

delete-TodoList リンクのすぐ上にあるindex.cshtmlに「並べ替えリンク」を追加しました。

<a href="#" data-bind="click: $parent.sortList">並べ替え</a>

次に、それをviewModel.jsに実装しました:

var sortAscending = true;
var ビューモデル = {
    ...
    ソートリスト: ソートリスト,
    ...
};
...
関数 sortList(リスト) {
    list.todos().sort(関数(左, 右) {
        return (sortAscending ? 1 : -1) *
            (left.title().toLowerCase() < right.title().toLowerCase() ? -1 : 1);
    });
    sortAscending = !sortAscending; // ソート方向を逆にする
    list.todos.valueHasMutated(); // ソートしたことを KO に知らせる
}

魅力のように機能します。Todo を自由に並べ替え、追加、削除します。追加および削除すると、アプリは期待どおりに保存されますが、保存中は保存されません。

試してみてくださいvalueHasMutated

于 2013-06-02T00:22:14.860 に答える