1

そのタイトルはかなり一口です。できる限りはっきりさせてください...

エンティティ フレームワークを使用して SQL Server からオブジェクトのリストにデータをプルする .NET 4 で記述された WCF REST サービスがあります。その後、オブジェクトは XML としてクライアントに返されます。問題は、モデルの関係により、XML が相互に参照していることです。

問題を説明するのに役立つコードを次に示します。

私のモデル: http://bara.stardock.com/images/activity_model.png

サービス ロジックを処理するアクティビティ クラス:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class Activities : IActivities
{
    public ActivitiesList GetActivities(string titleId, string accountId, string numToReturn)
    {
        stardockActivitiesEntities sdActivitiesDb = new stardockActivitiesEntities();

        int accountIdInt = int.Parse(accountId);

        List<Activity> items = (from a in sdActivitiesDb.Activities
                                join ab in sdActivitiesDb.ActivityBridges
                                    on a.ActivityID equals ab.ActivityID
                                where ab.AccountID == accountIdInt
                                select a).ToList();

        ActivitiesList list = new ActivitiesList(items);

        return list;
    }
}

上記のクラスのインターフェース:

[ServiceContract]
public interface IActivities
{
    [OperationContract]
    [WebGet(UriTemplate = "{titleId}/accounts/{accountId}/limits/{numToReturn}")]
    ActivitiesList GetActivities(string titleId, string accountId, string numToReturn);
}

Activity クラスは、Activities テーブルのモデルに基づいてエンティティ フレームワークによって自動生成されます。ただし、ActivitiesList オブジェクトを作成して、このクラスを拡張しました。

[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Stardock.CVP.Stats")]
public partial class Activity
{

}

[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Stardock.CVP.Stats")]
[DataContract(IsReference=false)]
public class ActivitiesList
{
    [DataMember]
    public List<Activity> Activities { get; set; }

    public ActivitiesList()
    {
        Activities = new List<Activity>();
    }

    public ActivitiesList(List<Activity> list)
    {
        Activities = new List<Activity>();

        foreach (Activity item in list)
        {
            Activities.Add(item);
        }
    }

    public void Add(Activity a)
    {
        Activities.Add(a);
    }
}

私の問題をもう一度説明すると、私の XML は単にアクティビティのリストを返すのではなく、基本アクティビティ内にある他のアクティビティを参照するいくつかのアクティビティを含むアクティビティのリストを返します。ややこしいですが、下の画像を見てください。

返される XML: http://bara.stardock.com/images/activity_xml1.png

「i8」の参照を持つアクティビティは、実際には「i2」の ID を持つアクティビティ内にある別のアクティビティを参照しています: http://bara.stardock.com/images/activity_xml2.png

私の質問は、Activity オブジェクトからこれらの余分な関係をすべて削除するにはどうすればよいですか? エンティティ フレームワークによって自動生成される、ネストされた ActivityType や EntityKey などを含まないアクティビティのリストにすることをお勧めします。

私は自分自身を十分に説明したことを願っています。そうでない場合は、その他の詳細をお知らせください。提供します。

バラ

4

2 に答える 2

1

ここには 2 つのオプションがありますが、どちらも少し作業が必要です。

私の推奨は、適切なデータを公開し、代わりにそれらを返すラッパー クラスを作成することです。

return new PersonWrapper() {Id = Person.Id, Name = Person.Name};

PersonWrapper は自動プロパティのみを必要とし、関連するプロパティを使用して、返すデータとその返される方法を正確に制御できます。

別の提案は、次のウォークスルーから得られます

これは、エンティティ フレームワークのコード生成に依存する代わりに、POCO クラス (これも手動で作成する必要があります) を使用することを提案しています。これは、慣例により (ほとんどの場合) 概念モデルのエンティティにマップされます (詳細はこちら: http:/ /blogs.msdn.com/b/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx )

2 番目のオプションでは、コード生成をオフにする必要があるため、いくつかのクラスのみを公開する予定がある場合、すべてのエンティティに対して POCO クラスを手動で作成する必要があるのはおそらく面倒です。そのため、ラッパー クラスのみを作成することをお勧めします。公開する必要のあるオブジェクト用

マーティン

于 2010-08-20T00:40:22.320 に答える
0

EF(4) を使用すると、モデル (デザイナーなど) で不要/不要な関連付けを削除できると思います。そうすれば、コード ジェネレーターは関係をナビゲートするためのプロパティを生成しません。

編集: 関連付けとは、実際の「関連付け」(図の線) とナビゲーション プロパティ (エンティティの下部) を意味します。

于 2010-08-07T12:24:42.260 に答える