0

linq クエリが機能しないのはなぜですか?

遅延読み込みと関係があるのではないかと思います。linqpadで動作するようです。

public IList<PaymentDto> GetDocumentPayments(int documentId, bool? allowRepeatPayments, byte[] paymentStatuses, int[] paymentMethods)
    {
        using (var ctx = ObjectContextManager<MyDataContext>.GetManager("MyDataContext"))
        {
            var payments = new List<PaymentDto>();

            var ps = new List<byte>();        
            if (paymentStatuses != null)
            {
                ps = paymentStatuses.ToList();
            }

            var pm = new List<int>();
            if (paymentMethods != null)
            {
                pm = paymentMethods.ToList();
            }

            IQueryable<Payment> data = 
                   from payment in ctx.ObjectContext.Documents.OfType<Payment>()
                   where
                       ps.Contains(payment.Status) && 
                       pm.Contains(payment.Method) &&
                       payment.DocumentId == documentId &&
                       (allowRepeatPayments == null || payment.AllowRepeatPayments == allowRepeatPayments)
                   orderby payment.Id
                   select payment;

            foreach (var p in data) // Fails here
            {
                payments.Add(ReadData(p));
            }

            return payments;
        }
    }

スローされるエラー: CollectionType が必要です。パラメータ名: collectionType.

4

2 に答える 2

1

like の構造体(allowRepeatPayments == null || payment.AllowRepeatPayments == allowRepeatPayments)は、クエリに対して面白いことを行うことができます。するとどうなるか試してください:

if (allowRepeatPayments.HasValue)
{
    data = data.Where(p => p.AllowRepeatPayments == allowRepeatPayments);
}

paymentStatusesとについても同じことができますpaymentMethods

それはあなたの問題を解決するかもしれませんが、そうでない場合でも、条件は必要な場合にのみ追加され、そうでない場合は SQL が乱雑にならないため、とにかく改善されます。

于 2012-06-29T17:36:43.523 に答える
0

例外は、LINQ クエリを SQL に変換しているときに、フレームワークの内部メソッドによってスローされます。使用しているのと同じ種類の null チェック用の構成体があります (たとえば、

.Where(data => x & y & (values == null || values.Contains(data.value)));)

.Net 4 RTM (4.0.30319.1)の最も古いバージョンを実行しているサーバーで同じ例外が発生しました。それはから来ます

   exception : System.ArgumentException: A CollectionType is required.
   Parameter name: collectionType

   at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateNewEmptyCollection(TypeUsage collectionType, DbExpressionList& validElements)
   at System.Data.Objects.ELinq.ExpressionConverter.NewArrayInitTranslator.TypedTranslate(ExpressionConverter parent, NewArrayExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) ...

このエラーはインターネット上では非常にまれであり、同じ条件と新しいバージョンでは発生しないため、.Net の最近のバージョンでは修正されているようです。

Gert Arnold の提案もおそらくエラーを回避することを可能にしますが、上記の形式は (SQL の対応物と同様に) 頻繁に使用され、短くて便利です。

したがって、このエラーがまだ発生し、一部のマシンで機能する理由と機能しない理由がわからない場合は、.Net FW バージョンを確認することをお勧めします。

于 2016-08-10T08:48:27.100 に答える