1

私は3層アプリケーションに取り組んでいます。また、データアクセスにLINQtoSQLを使用しています。

DataLayerには、顧客のテーブルを返す関数があります。

public Table<Customer> getCustomers()
{
    DataContext context = new DataContext();
    Table<Customer> customerTable = context.GetTable<Customer>();

    return customerTable;
}

これは、結果が次のようにプレゼンテーション層に渡されるビジネス層に提供されIEnumerable<Customer>ます。

public IEnumerable<Customer> getCustomers()
{
    CustomerDAL customerDAL = new CustomerDAL();

    return from c in customerDAL.getCustomers() select c;            
}

プレゼンテーション層では、DatagridViewのデータソースにIEnumerableを使用しているだけです。

「情報」のような別のテーブルとそれに対応するテーブルがある場合はどうなりcustomerDAL.getInfo()ますか?次に、Business-Layerのメソッドで結合クエリを作成します。私はそれを次のように想像しました:

public IEnumerable<Customer> getCustomerInfo()
{
    CustomerDAL customerDAL = new CustomerDAL ();

    return from c in customerDAL.getCustomers()
                  join i in customerDAL.getInfo() on c.id equals i.InfoID
                  select new { c.id, c.Name, i.DateTime, i.Project };
}

問題は、IEnumerableがオブジェクトのタイプを必要とすることです。私の戻り値は、もはや顧客テーブルではなく、顧客テーブルと情報テーブルの組み合わせです。私はそれを正しく理解しましたか?ここでの戻り値の正しい選択は何でしょうか?

あなたのアドバイスの後、私はカスタムクラスを作成しましたCustomerInfo.cs

public class CustomerInfo
    {        
        string name { get; set; }
        long id { get; set; }
        string dateTime { get; set; }
        string project { get; set; }


        public CustomerInfo(long _id, string _name, string _date, string _project) 
        {
            name = _name;
            id = _id;
            dateTime = _date;
            project = _project;
        }
    }

次に、Reedが説明したのとまったく同じメソッドを呼び出しています。しかし、データソースを設定すると、プレゼンテーション層で例外が発生します。

The query contains references to items defined on a different data context.

実際、これはすべてのエンティティクラスが同じ.dbmlファイルにあるわけではありません。何が間違っている可能性がありますか?

4

4 に答える 4

1

ここでの戻り値の正しい選択は何でしょうか?

厳密に型指定されたクラスを返したい場合は、クラスなど、この型を表すカスタム クラスが必要になりますCustomerInfo。このクラスを定義し、適切なプロパティとコンストラクターを含める必要があります。次に、次のことができます。

public IEnumerable<CustomerInfo> GetCustomerInfo()
{
        CustomerDAL customerDAL = new CustomerDAL();

        return from c in customerDAL.getCustomers()
                    join i in customerDAL.getInfo() on c.id equals i.InfoID
                    select new CustomerInfo(c.id, c.Name, i.DateTime, i.Project);
}

これにより、厳密に型指定された方法で、必要な正確な情報を返すことができます。この場合、カスタム クラスを作成することが特に重要であると主張します。これは、パブリック API の一部として定義されているためです。

于 2012-08-27T20:54:23.897 に答える
1

2番目のエラーについて:

次に、リードが説明したのとまったく同じメソッドを呼び出しています。しかし、DataSource を設定すると、Presentation-Layer で例外が発生します。クエリには、別のデータ コンテキストで定義された項目への参照が含まれています。

ほとんどの場合、DAL は、返すテーブルごとにコンテキストの個別のインスタンスをインスタンス化しています (ActiveRecord のパターン化された実装では典型的です)。結合が機能するには、両方のテーブルが同じコンテキスト オブジェクトによって取得される必要があります。コンテキストの有効期間を一元化できるように、DAL のコンストラクターにコンテキストを挿入するように DAL を変更することができます。

于 2012-08-28T17:31:25.447 に答える
0

そのような無名オブジェクトを作成すると、その型はdynamic. したがって、そのような匿名オブジェクトのリストを返すには、次のシグネチャを使用します。

public IEnumerable<dynamic> getCustomerInfo() {
    CustomerDAL customerDAL = new CustomerDAL ();

    return from c in customerDAL.getCustomers()
        join i in customerDAL.getInfo() on c.id equals i.InfoID
        select new { c.id, c.Name, i.DateTime, i.Project };
}

ただし、このdynamicタイプには欠点があることに注意してください。特に、見つけにくいバグを引き起こす可能性のある強い型付けが失われます。より堅牢なソリューションについては、Servy の回答を検討する必要があります。

于 2012-08-27T20:55:33.677 に答える
0

これまでのところ、すべてが良さそうです。単一のメソッドのスコープ内でクエリを使用するだけの場合は、匿名クラス (現在行っていること) を使用しても問題ありません。そうでないので、プロジェクションを返すことができるように、プロジェクションの具象クラスを作成する必要があります。

クエリは次のようになります。

select new SomeClassYouAreAboutToCreate { c.id, c.Name, i.DateTime, i.Project };

そのクラスには、おそらく一連のプロパティ 、idNameなどがあります。これらのプロパティを で設定するだけですSelect

于 2012-08-27T20:50:32.137 に答える