0

AngularJS ディレクティブ内で、新しい値をスコープ変数に割り当てます。

$scope.myPerson = { TiersId: 105191, Name: "John Smith" };

元の $scope.myPerson は BreezeJS エンティティから作成されました。

新しい値を割り当てると、AngularJS によって $scope.apply() がトリガーされ、BreezeJS によってインターセプトされます。その時は複雑になります。

[編集]

わかりました、dataContext に登録した EntityManager を使用する必要があることがわかりました。

$scope.myPerson =  myDataContext.createPerson({ TiersId: 105191, Name: "John Smith" });

  function createPerson(person) {
        return manager.createEntity("AccountOwner", person);
  }

現在、次のコードで失敗しています。

  proto.createEntity = function (typeName, initialValues, entityState) {
    entityState = entityState || EntityState.Added;
    var entity = this.metadataStore
        ._getEntityType(typeName)
        .createEntity(initialValues);
    if (entityState !== EntityState.Detached) {
        this.attachEntity(entity, entityState);
    }
    return entity;
};

エンティティ タイプはわかっていますが、createEntity(initialValues) 関数は定義されていません。どうして ?

[編集]

わかりやすくするために、関連する EF マッピングとモデル クラスを次に示します。

public class MandateMappings : EntityTypeConfiguration<Mandate>
{
    public MandateMappings()
    {
        Property(m => m.IBAN).HasMaxLength(34).IsFixedLength().IsUnicode(false);

        Property(m => m.AccountOwner.Name).HasMaxLength(70);  
        Property(m => m.AccountOwner.City).HasMaxLength(500); 

        Property(m => m.CreatedBy).HasMaxLength(30);
        Property(m => m.UpdatedBy).HasMaxLength(30);
    }
}



public class Mandate : Audit
{  
    public string IBAN { get; set; }

    public AccountOwner AccountOwner { get; set; }

}

public class AccountOwner
{
    public string Name { get; set; }
    public string City { get; set; }
}

public abstract class Audit
{
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
}
4

2 に答える 2

1

ユーザーの声で、Breeze は継承の形式をサポートしているが、「データベース継承」はサポートしていない と述べたときの意味を明確にさせてください。

今日、サーバー側のクラスは、そのチェーンがクライアントから見えない場合にのみ、継承チェーンの一部になることができるということです。

その警告と一致するいくつかの条件を次に示します。

  • チェーン内の「ターミナル」クラス (最も派生したクラス) のみがデータベース テーブルにマップされます。

  • スーパークラスのプロパティは、公開されていない (例: 内部) か、明示的にマップされていない (例: [System.ComponentModel.DataAnnotations.Schema.NotMapped].

  • メソッドはクライアントに送信されないため、メソッドは任意のレベルの任意のクラスに表示される可能性があります。

TodoItemから継承するクラスの例を次に示しbaseClassます。

パブリック クラス baseClass
{
    public void DoNothing() {}
    内部文字列 Foo { get; 設定; }
}
public class TodoItem :baseClass
{
    public int ID { get; 設定; }                   

    [必須、StringLength(最大長: 30)]   
    public string 説明 { get; 設定; }       

    public System.DateTime CreatedAt { get; 設定; }
    public bool IsDone { get; 設定; }              
    public bool IsArchived { get; 設定; }          
}

これはサーバー上で正常に機能します。コントローラーにブレークポイントを設定します。プロパティの実行DoNothing()と取得/設定に問題はありません。Foo

この構造のクライアント側の結果がないため、これは機能します。メタデータは、派生後baseClassも以前と変わりません。FooプロパティとDoNothingメソッドは、クライアントからは見えません。このサービスの作成者が意図したとおりです。

この種の配置は、ビジネス モデルの多くのクラスが基本クラスを通じて機能を共有する現実の世界では非常に一般的です。

これは話の終わりではなく、「継承」を求めるときに人々が求めていると私たちが考えているものでもありません.

私が「データベース継承」と呼んでいるのは、継承チェーン内の 2 つ以上のクラスが異なるテーブルにマップされることを意味するものです。

現在、Breeze はそれを処理していません。その理由の 1 つは、Breeze が継承階層を記述するメタデータをまだ理解できないためです。

回避策

データ プロパティが異なるクラス レベルで定義されているクラス階層があるとしたらどうでしょうか。クライアントの観点から階層を平坦化するメタデータの説明を提供することで、現在の障害を回避できます。

たとえば、 と のPerson型があるFirstNameとしLastNameます。Andはwhich Persondefine から派生します。entityBasecreatedBy

Person *EntityType* を [ FirstNameLastName、および] プロパティを持つように定義するとcreatedBy(基本的に階層がフラットになります)、すべてがうまくいきます。

階層を自動的にフラット化する

もちろん、それはPITAです。継承への 1 つのアプローチとして、Breeze にサーバー上でメタデータを生成するように依頼するときに、このフラット化を行うことができます。

私は興味があります: これで十分でしょうか? createdByそれとも、プロパティが基本クラスに属していることを JavaScript クライアントで本当に知る必要がありますか。本当に知りたいなら理由を教えてください。

于 2013-04-20T22:36:06.870 に答える