0

WCF RIA Services と Microsoft LightSwitch についての理解はかなり深まりましたが、今は途方に暮れています。例としてAnimalandを使用します。Dog私は実際にはゼロまたは 1対 1 の関係を望んでいます。すべての動物が必ずしも犬である/犬を飼っているわけではありません。

まず、RIA サービスで使用するデータベースに 1 対 1 の関係を作成します。次に、RIA Services プロジェクトの Model.edmx ファイルをいつものように更新します。問題は、これが私が期待していたようにアクセスできるようにする代わりにObjectContext.Dogs、それが存在せず、代わりに Animal に Dog の追加のプロパティが与えられていることです。どうやら 1 対 1 の関係はこのように特別に処理されているようで、これは役立つことを意図しているように見えますが、この方法で作業するのは非常に困難です。

私の RIA Services クラスは次のようになります。

public class RiaDog
{
    [Key]
    public int Id { get; set; }

    public int PackLeaderId { get; set; }

    [Association("RiaAnimal_RiaDog", "Id", "Id", IsForeignKey = true)]
    public RiaAnimal Animal { get; set; }
}

public class RiaAnimal
{
    [Key]
    public int Id { get; set; }

    [Association("RiaAnimal_RiaDog", "Id", "Id", IsForeignKey = false)]
    public RiaDog Dog { get; set; }
}

私が気付いていない何らかの魔法のような 1 対 1 のデータ注釈属性がない限り、RiaDog同様RiaAnimalのクラスや他のすべてのクラスに対して CRUD メソッドを作成する必要があります。ObjectContext.Dogs が存在しないという事実を考えると、これはかなり厄介です。アニマルを処理する必要があります。

[Query(IsDefault = true)]
public IQueryable<RiaDog> GetAllDogs() {
    var report = from animal in ObjectContext.Animals
                    where animal.PackLeader != null
                    select new RiaDog
                    {
                        Id = animal.Id,
                        PackLeaderId = animal.Dog.PackLeaderId,
                    };
    return report;
}

すでにこれは奇妙に感じます。犬を分離するために、Animal に与えられた Dog プロパティの 1 つで where 句を使用する必要があります。

簡単な工夫で、insert、update、および delete メソッドを機能させることができます。

public void InsertDog(RiaDog riaDog) {
    var animal = ObjectContext.Animals.FirstOrDefault(a => a.Id == riaDog.Id);
    animal.PackLeader = ObjectContext.PackLeaders.FirstOrDefault(pl => pl.Id == riaDog.PackLeaderId);
    riaDog.Animal.Dog = riaDog;
}

public void UpdateDog(RiaDog rd) {
    var animal = ObjectContext.Animals.FirstOrDefault(a => a.Id == riaDog.Id);
    animal.PackLeader = ObjectContext.PackLeaders.FirstOrDefault(pl => pl.Id == riaDog.PackLeaderId);
}

public void DeleteDog(RiaDog rd) {
}

で、UpdateAnimal()設定した後方参照を使用しInsertDog()て追加します。

if (riaAnimal.Dog == null)
    riaAnimal.PackLeader = null;

また、データベース上で Animal を使用してカスケード削除するように Dog を設定しています。

LightSwitch フロントエンドでは、RiaDog エンティティでこれを使用しています。

partial void AnimalType_Changed() {
    if (AnimalType != null && AnimalType.Name == "Dog" && this.Dog == null)
        this.Dog == new RiaDog();
    else if (this.Dog != null && (AnimalType == null || AnimalType.Name != "Dog"))
        this.Dog = null;
}

私が抱えている問題は、タイプをDogに変更して保存し、別のものに戻して保存し、次に再びDogに変更して保存すると、エラーが表示されることです:The context is already tracking a different entity with the same resource Uri.


私は他の追跡エラーを処理することを学びました:

  • コード ビハインド クライアント側でエンティティを作成する場合、クライアント側で適切に追跡するには一意の ID が必要です。

  • WCF RIA サービスの挿入メソッドでは、データベースが生成した後、エンティティのクライアント ID を実際の ID に設定する必要があります。次に例を示します。

 

public void InsertRiaEntity(RiaEntity re) {
    var entity = new Entity();
    entity.SomeProperty = re.SomeProperty;
    entity.AnotherProperty = re.AnotherProperty;
    ObjectContext.Entities.AddObject(entity);
    ObjectContext.SaveChanges();
    // essential for client<->server tracking
    re.Id = entity.Id;
}

ただし、この現在の追跡エラーを解決する方法がわかりません。本当に私は間違ったアプローチを取っているように感じます。WCF RIA Services for Microsoft で1 対 1 または1 または 0対 1 の関係をコーディングする方法について、専門家のアドバイスを探しています。電気のスイッチ。

私は実際にこれをすべて1対多の関係で機能させることができました。要するに、「正しい」ように見える十分なコードであるため、このバリエーションは実現可能です。

4

1 に答える 1

1

LightSwitch は実際には 1 対 1 の関係をサポートしていないため、RIA サービスで成功したとしても、LightSwitch では機能しませんでした。

回避策は、ゼロ対多または 1 対多の多重度の関係を作成することです (最終的に行ったように)。検証またはコードで1対1を「強制」する必要があります。

于 2013-04-18T10:12:33.223 に答える