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

像这样的构造(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 时抛出异常,使用与您使用的相同类型的空检查构造(例如

.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 回答