1

Entity Framework を使用して、3 つのテーブルから ListView にデータを入力するレコードを取得しようとしています。

これらのテーブルの構造の例は次のとおりです。

luPersonType

PersonTypeID
PersonTypeDescription

人々

PersonID
FirstName
LastName
{...}
PersonTypeID

従業員情報

EmployeeInfoID
PersonnelNumber
StartDate
{...}
PersonID

luPersonType は、人のタイプを区別するために使用される 2 つの値 (「Customer」と「Employee」) を保持するルックアップ テーブルです。luPersonType は People に対して 1:M の関係を持ちます。

個人が従業員である場合、従業員に関する追加の詳細が EmployeeInfo テーブルに格納されます。People は EmployeeInfo と 1 対 1 (理論上) の関係にあります。

サンプルデータ:

luPersonType

PersonTypeID----PersonTypeDescription
1---------------Customer
2---------------Employee

人々

PersonID----FirstName---LastName---PersonTypeID
1-----------Jane--------Doe--------1
2-----------John--------Doe--------2
3-----------Bob---------Smith------1
4-----------Sue---------Jones------2

従業員情報

EmployeeInfoID----PersonnelNumber----StartDate----PersonID
1-----------------ABC123-------------1/1/13-------2
2-----------------XYZ456-------------2/1/13-------4

ご覧のとおり、John と Sue はどちらも Employees であり、それぞれ EmployeeInfo テーブルにレコードを持っています。

PersonType の説明と EmployeeInfo の詳細 (存在する場合) を含むすべての人のリストを返したいと思います。

luPersonType.PersonTypeDescription,
People.LastName + ", " + People.FirstName AS FullName,
EmployeeInfo.PersonnelNumber,
EmployeeInfo.StartDate

これにより、次のようになります。

PersonTypeDescription----FullName----PersonnelNumber----StartDate
Customer-----------------Doe, Jane---NULL---------------NULL
Employee-----------------Doe, John---ABC123-------------1/1/13
Customer-----------------Smith, Bob--NULL---------------NULL
Employee-----------------Jones, Sue--XYZ456-------------2/1/13

私は最初にこのコードを試しましたが、People と EmployeeInfo の両方にレコードを持つ People しか返されませんでした (内部結合?):

using(MyEntities ctx = new MyEntities())
{
    var query = from a in ctx.People
                join b in ctx.luPersonType on a.PersonTypeID equals b.PersonTypeID
                join c in ctx.EmployeeInfo on a.PersonID equals c.PersonID
                orderby a.LastName
                select new
                {
                    b.PersonTypeDescription,
                    FullName = a.LastName + ", " + a.FirstName,
                    c.PersonnelNumber,
                    c.StartDate
                };

    RadListViewPeople.DataSource = query.ToList();
}

その結果、内部結合が発生するように見えたので、このクエリを作成するさまざまな方法を調べました。これが私の2回目の試みです:

using (MyEntities ctx = new MyEntities())
{
    var query = from a in ctx.People
                orderby a.LastName
                select new
                {
                    a.luPersonType.PersonTypeDescription,
                    FullName = a.LastName + ", " + a.FirstName,
                    PersonnelNumber = from b in a.EmployeeInfos
                                      select b.PersonnelInfo
                    StartDate = from b in a.EmployeeInfos
                                select b.StartDate
                }
}

これは 4 つのレコードすべてを返しましたが、PersonnelNumber (System...String) と StartDate (System...DateTime) のデータ型を返しました。

.Include メソッドについて読んだことがありますが、それを機能させることもできませんでした。

2 番目のクエリでは、必要なすべてのレコードが得られ、すっきりしているように見えますが、EmployeeInfo から実際のデータ値を取得する方法がわかりません。

どんな助けでも大歓迎です!

4

1 に答える 1

1

モデルが適切にセットアップされていれば、これを簡単に実行できるはずです (注: テストしていないため、構文が正しいとは 100% 確信が持てませんが、問題を解決するために必要なものが得られるはずです。また、ナビゲーション プロパティ EmployeeInfo の名前を推測します):

var query = from a in ctx.People
            let b = a.EmployeeInfo.FirstOrDefault()
            orderby a.LastName
            select new {
                a.luPersonType.PersonTypeDescription,
                FullName = a.LastName + ", " + a.FirstName,
                b.PersonnelNumber,
                b.StartDate
            };

ここでの問題は、1:1 としてのみ使用する場合でも、PersonnelInfo が実際には 1:many であるため、関連付けがない場合に null を返すように最初のレコードまたはデフォルトを選択する必要があることです。

注: EF は null 参照を問題として扱わないため、これは IQueryable を使用している場合にのみ機能します。これが IEnumerable に変換された場合、一部のレコードでは b が null になるため、上記のコードは PersonnelNumber と StartDate で execption をスローします。

于 2013-09-13T01:53:06.127 に答える