0

WCFで動作するようにEFをセットアップし、ドメインクラスモデルをEFAgnosticに維持しようとしています。

コードは3つのプロジェクトに編成されています。(私はDDDを突き刺しています-私はそれに非常に新しいですが、もっと学ぶことを楽しみにしています)

    プロジェクト:QA-ドメインレイヤー。DataContractモデル/エンティティが含まれています。
        参考文献
            QA。データ

    プロジェクト:QA.Data-データレイヤー。コンテキストとEDMXが含まれています(コード生成戦略= "none")
        参考文献
            Entity Framework / System.Data.Entity

    プロジェクト:QA.Repository-データアクセス/リポジトリ。リポジトリクラスが含まれています
        参考文献
            QA[ドメインレイヤー]
            QA.Data[データレイヤー]
            エンティティフレーム/System.DataEntity

私の理解では、ドメインレイヤーはデータレイヤーを参照できますが、データレイヤーはドメインを参照してはなりません。これがもたらす問題は、私のドメインモデル/クラスがドメインレイヤーで定義されているが、それらを作成して返すコンテキストがデータレイヤーにあることです。私のコンテキストが「ウィジェット」オブジェクトを返すことを知るためには、「ウィジェット」を定義したドメインレイヤーへの参照が必要になります

私の(失敗した)解決策:私の解決策は、各ドメインモデルのインターフェイスを作成し、それらをデータレイヤーに配置することでした。コンテキストは...IdbSetを返します...これらのインターフェイスはドメインモデルによって実装されるため、データレイヤーがドメインを直接参照する必要がなくなります(とにかく不正な循環参照が発生します)。ドメインモデルは元々、「ADO.NET DbContext Generator w/WCFSupport」T4テンプレートを使用して構築されました。このプロセスにより、ウィジェットクラス定義の先頭に[KnownType(typeof(IWidgetPiece))]が含まれるようになりました。(ウィジェットにはナビゲーションプロパティがあります... ICollection ...)

サービスにアクセスしようとすると問題が発生し、次のエラーが発生します

「QA.Data.IWidgetPiece」は、同じデータコントラクト名「http://www.w3.org/2001/XMLSchema:anyType」を持つ別のタイプ「System.Object」がすでに存在するため、既知のタイプのリストに追加できません。特定のタイプの異なるコレクション(たとえば、ListとTest [])がある場合、それらを両方とも既知のタイプとして追加することはできません。既知のタイプのリストに追加するには、これらのタイプの1つだけを指定することを検討してください。

これらを具体的な実装に変更できます...[KnownType(typeof(WidgetPiece))] ...しかし、参照しているナビゲーションプロパティがまだIWidgetPieceインターフェイスタイプを返しているため、このエラーが発生し続けます。インターフェイスの実装を満足させるため。

私は物事を適切に分割し、それでもコンテキストが本来あるべきものを返す方法を見つけようとしています。インターフェイスを返すコンテキストは、これや他の理由でまだ私に「座って」いないが、これを行う別の方法を考えることはできず、これでも前述の問題が発生している。ヘルプ!

うまくいけば私の以前のとりとめのないことを明確にするためのいくつかのコード...

namespace QA.Data
{

    public interface IWidgetPiece
    {
        String ID { get; set; }
    }

    public interface IWidget
    {
        String ID { get; set; }
        ICollection<IWidgetPiece> Pieces;    
    }

    public partial class WidgetEntities : DbContext
    {
        IDbSet<IWidget> Widgets { get; set; }
        IDbSet<IWidgetPiece> WidgetPieces { get; set; }
    }

}


namespace QA
{
    [KnownType(typeof(IWidgetPiece))]
//  [KnownType(typeof(WidgetPiece))]
    [DataContract(IsReference = true)]
    public partial class Widget : QA.Data.IWidget
    {
        [DataMember]
        public String ID { get; set; }
        [DataMember]
        public virtual ICollection<IWidgetPiece> Pieces { get; set; }
    }

    [DataContract(IsReference = true)]
    public partial class WidgetPiece : QA.Data.IWidgetPiece
    {
        [DataMember]
        public string ID { get; set; }
    }

}


namespace QA.Repository
{
    public class WidgetRepository
    {
        public List<Widget> GetWidgetbyID(String sId)
        {
            WidgetEntities context = new WidgetEntities();
            List<IWidget> objs = context.Widgets.Where(b => b.ID == "78").ToList();

            List<Widget> widgetList = new List<Widget>();
            foreach (var iwidget in widgetList)
                widgetList((Widget)iwidget);

            return widgetList;
        }
    }
}
4

1 に答える 1

0

データ アクセス レイヤー モデル (edmx) と「実際の」ドメイン モデルという 2 つの別個のモデルが本当に必要ですか? EF のような ORM フレームワークの要点は、物理 (データベース) 概念モデル間のマッピングを使用して、ドメイン モデルをデータベース テーブルにマッピングできるようにすることです。

EF4.1 以降、ドメイン モデルを構築し、データ アクセス レイヤーで流暢な API を使用して直接データベースにマップできます。すぐに実行に移したい場合は、データベースから POCO ドメイン モデルをリバース エンジニアリングすることもできます。

EF クラス モデル全体を作成するのは少し不必要に複雑に思えますが、それを別のクラス モデル (EF によって生成されたモデルにかなり近いものになる可能性が高い) に再度マップする必要があります。

于 2012-10-03T21:29:45.937 に答える