在C#中使用VS 2017 我有一个扩展范围的工作解决方案。 最初它只需要返回一个数据集,其中如果line.RMANumber包含或以两个不同的变量开始,则goodRMA_flag被设置为true。
这是原始代码,工作正常:
string mask1 = "/078";
string mask2 = "078";
//start with all of them, flag the good and bad
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
{
DatetimeCreated = line.DatetimeCreated,
UniqueIdNo = rma.UniqueIdNo,
RmaNumber = line.RmaNumber,
RmaOriginalUniqueId = line.RmaOriginalUniqueId,
ItemSequenceNo = line.ItemSequenceNo,
ItemNumber = line.ItemNumber,
goodRMA_flag = (line.RmaNumber.Contains(mask1) || line.RmaNumber.StartsWith(mask2)),
RMA_cleanedUp = line.RmaNumber.Substring(line.RmaNumber.IndexOf("/") + 1)
}).ToArray();
现在他们已经将要求扩展到可能需要任意数量的面具的地方。 我正在使用以下代码构建所有需要匹配的列表:
int startingMask = 75;
int numberNumberNeeded = 10;
List<string> masksContains = new List<string>();
List<string> masksStartsWith = new List<string>();
while (numberNumberNeeded > 0)
{
string newMask = (++startingMask).ToString().PadLeft(3, '0');
masksStartsWith.Add(newMask);
newMask = newMask.PadLeft(4, '/');
masksContains.Add(newMask);
numberNumberNeeded--;
}
现在我有了列表,我想将goodRMA_flag的行更改为:
goodRMA_flag = (line.RmaNumber.Contains(masksContains) || line.RmaNumber.StartsWith(masksStartsWith)),
我假设我需要某种Lamda,但是尽管有多次波动,我还是无法使语法正确。
编辑: 使用 -
goodRMA_flag = (masksContains.Any(masks => line.RmaNumber.Contains(masks)) ||
masksStartsWith.Any(masks => line.RmaNumber.StartsWith(masks))),
给出运行时错误: &#34; System.NotSupportedException:&#39;本地序列不能用于查询运算符的LINQ to SQL实现,但Contains()运算符除外。&#39;
解决方案 - 这是最终的工作代码供参考:
//a integer that we are starting with - this needs to come from
//a database at some point
int startingMask = 75;
//how far ahead to look
int qtyNeeded= 10;
//will hold the strings that RMA_Number needs to contain
List<string> masksContains = new List<string>();
//will hold the strings that RMA_Number needs to start with
List<string> masksStartsWith = new List<string>();
//Build the two lists
while (qtyNeeded> 0)
{
string newMask = (++startingMask).ToString().PadLeft(3, '0');
masksStartsWith.Add(newMask);
newMask = newMask.PadLeft(4, '/');
masksContains.Add(newMask);
qtyNeeded--;
}
//start with all of them, flag them all as bad -- will then step through and fix
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 RMA_Items
{
DatetimeCreated = Convert.ToDateTime(line.DatetimeCreated),
UniqueIdNo = rma.UniqueIdNo,
RmaNumber = line.RmaNumber,
RmaOriginalUniqueId = Convert.ToDecimal(line.RmaOriginalUniqueId),
ItemSequenceNo = Convert.ToDecimal(line.ItemSequenceNo),
ItemNumber = line.ItemNumber,
goodRMA_flag = false,
RMA_cleanedUp = line.RmaNumber.Substring(line.RmaNumber.IndexOf("/") + 1)
}).ToArray();
//convert it to a new list that we can step through
var rmaStopsAllList = RMA_stops_all.ToList();
//go through the new list, set the goodRMA_flag for the items that meet our criteria
rmaStopsAllList.ForEach(x => x.goodRMA_flag =
(masksContains.Any(masks => x.RmaNumber.Contains(masks))
|| masksStartsWith.Any(masks => x.RmaNumber.StartsWith(masks)))&&
x.RMA_cleanedUp.Length==10);
//flip it back into our original array
RMA_stops_all = rmaStopsAllList.ToArray();
//pull out the good ones
var RMA_Stops_GoodRMA = (from R in RMA_stops_all
where R.goodRMA_flag == true
select R).ToArray();
//pull out the bad ones
var RMA_Stops_BadRMA = (from B in RMA_stops_all
where B.goodRMA_flag == false
select B).ToArray();
除了新课程外:
class RMA_Items
{
public DateTime DatetimeCreated { get; set; }
public decimal UniqueIdNo { get; set; }
public decimal ItemSequenceNo { get; set; }
public string RmaNumber { get; set; }
public decimal RmaOriginalUniqueId { get; set; }
public string ItemNumber { get; set; }
public bool goodRMA_flag { get; set; }
public string RMA_cleanedUp { get; set; }
}
答案 0 :(得分:2)
我假设line.RmaNumber
应该包含masksContains
中可用的任何掩码。或者,line.RmaNumber
或者应该从masksStartsWith
中定义的一个掩码开始。如果符合上述任何条件,则goodRMA_flag
将设置为true
。希望这就是你要找的东西:
goodRMA_flag = (masksContains.Any(masks => line.RmaNumber.Contains(masks))
|| masksStartsWith.Any(masks => line.RmaNumber.StartsWith(masks)))
编辑:但是由于LINQ to SQL不允许这样做,因为line.RmaNumber
直接来自SQL,我们可以在RmaNumber
以后的下一步更新标志在对象中可用。
var rmaStopsAllList = RMA_stops_all.ToList();
rmaStopsAllList.Foreach(x => x.goodRMA_flag =
(masksContains.Any(masks => x.RmaNumber.Contains(masks))
|| masksStartsWith.Any(masks => x.RmaNumber.StartsWith(masks))));
RMA_stops_all = rmaStopsAllList.ToArray();
编辑2:还需要声明一个实际的类而不是使用匿名类型,以便以后可以将其分配(如上所示)。 goodRMA_flag
应该是类中的属性,并且可以在上一步中设置为任何值。
select new SomeClass
{
// Other initialization here
goodRMA_flag = false,
}).ToArray();
而不是
select new
{
// Other initialization here
goodRMA_flag = false,
}).ToArray();
最重要的是,请务必使用正确的数据类型为此目的添加新的类定义:
public class SomeClass
{
public string DateTime DatetimeCreated {get; set;}
public string UniqueIdNo {get; set;}
public string RmaNumber {get; set;}
public int RmaOriginalUniqueId {get; set;}
public string ItemSequenceNo {get; set;}
public string ItemNumber {get; set;}
public bool goodRMA_flag {get; set;}
public string RMA_cleanedUp {get; set;}
}
答案 1 :(得分:0)
编辑: 主要问题是这是LinqToSql,他在select语句中引用了一个本地序列。 您必须获得结果并使用本地结果创建一个新对象。
希望我没有弄错你的问题。
string data = @"<Error>
<Code>AccessDenied</Code>
<Message>Request has expired</Message>
<Expires>2017-03-31T14:49:56Z</Expires>
<ServerTime>2017-05-04T11:32:40Z</ServerTime>
<RequestId>...</RequestId>
<HostId>...</HostId>
</Error>";
XDocument xdoc = XDocument.Parse(data);
if(xdoc.Descendants("Error").Any())
{
var errorMessage = from lv1 in xdoc.Descendants("Error")
select lv1.Element("Message").Value;
Console.WriteLine(errorMessage.FirstOrDefault());
}
如您所见,只需要检查包含。
1,41和ka,实现了。