2

まず、この質問に対する答えを探しましたが、使用している機能が何と呼ばれているのかわからないため、何も見つかりませんでした。

以下のコードのDBEntitiesは、OracleDB接続用にdevartによって生成されました。

最初の例が機能し、2番目の例ではSystem.NullReferenceExceptionしか表示されないのはなぜですか?

有効なコード:

using (DBEntities context = new DBEntities())
{
    var infos = (from info in context.Infos
                 where info.Index == index
                 orderby info.Name
                 select new
                 {
                     Name = info.Name,
                     MRN = info.MRN,
                     UnitNumber = (info.UnitNum == null) ? -1 : (decimal)info.UnitNum,
                     UnitName = (info.UnitName == null) ? String.Empty : info.UnitName
                 }).Distinct();

    foreach (var info in infos)
    {
        // *do stuff*
    }
}

例外を与えるコード(例外はforeachに到達した場合にのみ表示されます):

using (DBEntities context = new DBEntities())
{
    var infos = (from info in context.Infos
                 where info.Index == index
                 orderby info.Name
                 select new Member()
                 {
                     Name = info.Name,
                     MRN = info.MRN,
                     CurrentUnit = new Unit()
                     {
                         UnitNumber = (info.UnitNum == null) ? -1 : (decimal)info.UnitNum,
                         UnitName = (info.UnitName == null) ? String.Empty : info.UnitName
                     }
                 }).Distinct();

    foreach (Member info in infos)
    {
        // *do stuff*
    }
}

編集: これも同様に機能することを追加したいと思います:

using (DBEntities context = new DBEntities())
{
    var infos = (from info in context.Infos
                 where info.Index == index
                 orderby info.Name
                 select new Member()
                 {
                     Name = info.Name,
                     MRN = info.MRN
                 }).Distinct();

    foreach (Member info in infos) //Exception is thrown here.
    {
        // *do stuff*
    }
}
4

2 に答える 2

2

最初の方法は、SQLからこれらの匿名型を返すことができ、EFが式全体のSQLステートメントを生成できるために機能します。2つ目は、SQLでMemberクラスのインスタンスを作成できないためです。(AsEnumerable()を使用して)列挙を強制的に実行した場合は、メンバー値のクライアント側を作成できます。

LINQは設計上、完全に「遅延」であるため、例外は常に列挙の時点でスローされます。式を作成した時点で(たとえば、テスト目的で)強制的に発生させたい場合は、式.ToList()の最後に追加します。

于 2012-04-06T22:23:25.750 に答える
0

それ以外の

foreach (Member info in infos) //Exception is thrown here.
{
    // *do stuff*
}

使用する

foreach (var info in infos) //Valid.
{
    // *do stuff*
}

これは、infos匿名の結果を返すためです。これは完全なMemberコレクションクラスではありません。

于 2012-04-06T22:27:14.560 に答える