我在Linq查询中的字符串上使用Split方法,但只需要第二个元素。我在下面的代码中得到一个“System.InvalidOperationException:'无法识别的表达式节点:ArrayIndex'”:
var RMA_stops_all = (from rma in rDb.DistributionStopInformations
join line in rDb.DistributionLineItems on rma.UniqueIdNo equals line.UniqueIdNo
where line.RmaNumber != null
&&
(line.DatetimeCreated > Convert.ToDateTime(dateToCheck_rma) &&
line.DatetimeCreated < Convert.ToDateTime(dateToCheck_rma).AddDays(7))
&& rma.CustomerNo == TNGCustNo
select new
{
dtCreated = line.DatetimeCreated,
UniqueIdNo = rma.UniqueIdNo,
RmaNumber = line.RmaNumber,
RmaOriginalUniqueId = line.RmaOriginalUniqueId,
ItemSequenceNo = line.ItemSequenceNo,
ItemNumber = line.ItemNumber,
goodRMA_flag = line.RmaNumber.Contains("/078"),
rmaGood = line.RmaNumber.Split(new string[] { "/" }, StringSplitOptions.None)[1]
}).ToArray();
如果我删除数组上的[1]它可以工作,我可以使用以下方法访问整个数据集的两个元素:
foreach (var item in RMA_stops_all)
{
var right = RMA_stops_all.First().rmaGood[1];
var left = RMA_stops_all.First().rmaGood[0];
Console.WriteLine("left {0} - right{1} ",left.ToString(), right.ToString());
}
编辑 - 呃。上面的“测试”是完全没用的(如同轻轻指出的那样) - 但是,下面确实证明它正常工作(一些返回的值只有1个元素,因此额外的if块 - 输出是预期的:
foreach (var item in RMA_stops_all)
{
string right, left;
if (item.rmaGood.Length == 1)
{
left = item.rmaGood[0].ToString();
right = "Not there";
}
else
{
left = item.rmaGood[0].ToString();
right = item.rmaGood[1].ToString();
}
Console.WriteLine("left {0} - right{1} ", left, right);
}
dbMonitor的SQL输出:
SELECT t2.datetime_created AS "DatetimeCreated",
t1.unique_id_no AS "UniqueIdNo",
t2.rma_number AS "RmaNumber",
t2.rma_original_unique_id AS "RmaOriginalUniqueId",
t2.item_sequence_no AS "ItemSequenceNo",
t2.item_number AS "ItemNumber",
(t2.rma_number LIKE :p3) OR (t2.rma_number LIKE :p4) AS "C1",
t2.rma_number AS "RmaNumber1"
FROM cops_reporting.distribution_stop_information t1
INNER JOIN cops_reporting.distribution_line_items t2
ON t1.unique_id_no = t2.unique_id_no
WHERE (t2.rma_number IS NOT NULL)
AND (t2.datetime_created > :p0)
AND (t2.datetime_created < :p1)
AND (t1.customer_no = :p2)
答案 0 :(得分:1)
我没有意识到Linq to Entities可以直接访问某些SQL函数,所以这可能对您有用:
var RMA_stops_all = (from rma in rDb.DistributionStopInformations
join line in rDb.DistributionLineItems on rma.UniqueIdNo equals line.UniqueIdNo
where line.RmaNumber != null
&&
(line.DatetimeCreated > Convert.ToDateTime(dateToCheck_rma) &&
line.DatetimeCreated < Convert.ToDateTime(dateToCheck_rma).AddDays(7))
&& rma.CustomerNo == TNGCustNo
select new
{
dtCreated = line.DatetimeCreated,
UniqueIdNo = rma.UniqueIdNo,
RmaNumber = line.RmaNumber,
RmaOriginalUniqueId = line.RmaOriginalUniqueId,
ItemSequenceNo = line.ItemSequenceNo,
ItemNumber = line.ItemNumber,
goodRMA_flag = line.RmaNumber.Contains("/078"),
rmaGood = line.RmaNumber.Substring(line.RmaNumber.IndexOf("/")+1)
}).ToArray();
假设RmaNumber看起来像#/#并且没有你想要避免的额外斜杠。
答案 1 :(得分:0)
我不明白为什么没有索引操作它会工作,你的SQL似乎没有反映相同的Linq代码(你使用过LinqPad吗?),但我建议你自己做.ToArray( )无论如何,将分割/索引移动到客户端:
var RMA_stops_all = (from rma in rDb.DistributionStopInformations
join line in rDb.DistributionLineItems on rma.UniqueIdNo equals line.UniqueIdNo
where line.RmaNumber != null
&&
(line.DatetimeCreated > Convert.ToDateTime(dateToCheck_rma) &&
line.DatetimeCreated < Convert.ToDateTime(dateToCheck_rma).AddDays(7))
&& rma.CustomerNo == TNGCustNo
select new
{
dtCreated = line.DatetimeCreated,
rma.UniqueIdNo,
line.RmaNumber,
line.RmaOriginalUniqueId,
line.ItemSequenceNo,
line.ItemNumber,
goodRMA_flag = line.RmaNumber.Contains("/078"),
}).AsEnumerable().Select(r => new {
r.dtCreated,
r.UniqueIdNo,
r.RmaNumber,
r.RmaOriginalUniqueId,
r.ItemSequenceNo,
r.ItemNumber,
r.goodRMA_flag,
rmaGood = r.RmaNumber.Split(new string[] { "/" }, StringSplitOptions.None)[1]
});
顺便说一句,您不必为简单的访问器表达式重复字段/属性名称,因此我将其从原始选择中删除。此外,如果您可以使用双重间接,则可以在第二个选择中包含r。