Waleed Abukatab Ответов: 4

Как проверить, что значение, разделенное запятыми, содержит другой массив в linq


У меня есть два стола Процесс И заказано.
теперь мне нужно получить процесс, который содержит все costCenterID из списка деталей заказа.
List<Process > process= new List<Process >()
 {
  new Process{Id=1, Name="Process 01", CostCenter="1,2,3,4" , companyID = 1  },
  new Process{Id=2, Name="Process 02", CostCenter="1,4,10"  , companyID = 1  },
  new Process{Id=3, Name="Process 03", CostCenter="1,2,5"   , companyID = 1  },
    }

 List<orderDetails> orderDetails= new List<orderDetails>()
 {
   new orderDetails{ Id=1, Name="order 01", CostCenterId ="1" , companyID = 1},
   new orderDetails { Id=2, Name="order 02", CostCenterId="2" , companyID = 1},
 }

Я пробовал этот код , но он не сработал, заметьте, использовал linq

var orderDetails = db.OrderDetails.Where(c => c.OrderId == order.Id);
    var orderCostCenter = orderDetails.Select(c => c.CostCenterId).ToArray();
    var listProcess = process.where (c=>c.companyID  == 1 &&
                  c.CostCenter.split(',').containt(orderCostCenter)).firstorDefault();

результат запроса linq возвращает два столбца=
new Process{Id=1, Name="Process 01", CostCenter="1,2,3,4" , companyID = 1  },
  new Process{Id=3, Name="Process 03", CostCenter="1,2,5"   , companyID = 1  },


Что я уже пробовал:

Я устал искать и решать этот вопрос, пожалуйста, помогите мне.

BillWoodruff

Что не так с текущим выходом ?

Пожалуйста, покажите пример того, что будет правильным выходом.

Предложение: рассмотрите возможность использования флагов перечисления на центр затрат, а не массив строк, чтобы упростить анализ.

Waleed Abukatab

мне нужен этот вывод с помощью linq :
{ИД=1, имя="процесс 01", центр затрат="1,2,3,4" , companyID = 1 },
{ИД=3, имя="процесс 03", центр затрат="1,2,5" , companyID = 1 },

4 Ответов

Рейтинг:
1

OriginalGriff

Что Linq не компилируется: у вас отсутствуют точки с запятой, "where" должно быть "Where", orderDetails не содержит OrderId (или вы вообще не устанавливаете его значение), "split" должно быть "Split", "containt" должно быть "Contains", а "firstorDefault" должно быть "FirstOrDefault". И вы определенно не должны создавать свой собственный класс под названием "Процесс" ...

Это означает, что Linq, который вы показываете, бесполезен, поскольку он не был протестирован вами и, следовательно, не дает никаких результатов, а тем более тех, которые вы свободно описываете.

И если вы не протестировали его, то и мы не можем - поэтому мы понятия не имеем, как выглядят ваши фактические входы или какие выходы вы ожидаете.

Покажите нам фактический код copy'n'paste, который компилируется, покажите нам фактические входные данные, покажите нам фактический вывод и ожидаемый вывод.

И сделайте себе одолжение: C# богат коллекциями, так зачем хранить какой-либо список как разделенный запятыми? Вместо этого используйте набор ссылок на фактические элементы CostCenter, и ваша жизнь в любом случае станет намного проще ...


BillWoodruff

+5

Рейтинг:
1

George Swan

Хитрость здесь заключается в том, чтобы использовать Intersect метод выбора совпадающих значений в 2-х строковых массивах.Тогда использовать Count() чтобы проверить, есть ли совпадение с тем же количеством, что и у вас. orderCostCenter.


var orderCostCenter = orderDetails.Select(c => c.CostCenterId);
var listProcess = process.Where(c => c.companyID == 1 &&
  c.CostCenter.Split(',').Intersect(orderCostCenter).Count() == orderCostCenter.Count());


Maciej Los

5ed!

George Swan

Спасибо,Мацей. сайт кажется немного медленным обновлением сегодня.

Рейтинг:
0

Maciej Los

Цитата:
мне нужен этот вывод с помощью linq :
{ИД=1, имя="процесс 01", центр затрат="1,2,3,4" , companyID = 1 },
{ИД=3, имя="процесс 03", центр затрат="1,2,5" , companyID = 1 },


Если CostCenterId это упорядоченный список, вы можете попробовать что-то вроде этого:
void Main()
{

	List<Process > process= new List<Process >()
	{
		new Process{Id=1, Name="Process 01", CostCenter="1,2,3,4" , companyID = 1  },
		new Process{Id=2, Name="Process 02", CostCenter="1,4,10"  , companyID = 1  },
		new Process{Id=3, Name="Process 03", CostCenter="1,2,5"   , companyID = 1  },
	};
	
	List<orderDetails> orderDetails= new List<orderDetails>()
	{
		new orderDetails{ Id=1, Name="order 01", CostCenterId ="1" , companyID = 1},
		new orderDetails { Id=2, Name="order 02", CostCenterId="2" , companyID = 1},
	};

	var result = process
		.Where(x=> x.CostCenter.Contains(string.Join(",", orderDetails.Select(o=> o.CostCenterId))))
		.ToList();
	foreach(var r in result)
		Console.WriteLine($"Id={r.Id}\tName='{r.Name}'\tCostCenter='{r.CostCenter}'\tcompanyID={r.companyID}");
}

// Define other methods and classes here
public class Process
{
	public int Id;
	public string Name;
	public string CostCenter;
	public int companyID;
}

public class orderDetails
{
	public int Id;
	public string Name;
	public string CostCenterId;
	public int companyID;
}


Результат:
Id=1  Name='Process 01'  CostCenter='1,2,3,4'  companyID=1
Id=3  Name='Process 03'  CostCenter='1,2,5'  companyID=1


Рейтинг:
0

K-Dhaduk

Привет ,

Вы можете использовать Intersect и SequenceEqual для сравнения двух массивов и получения нужного вам результата.

var finalList = new List();
            process.ForEach(y =>
            {
                var vardata = orderDetails.Select(x => x.CostCenterId).ToArray();
                var data1 = y.CostCenter.Split(',').Intersect(vardata);
                if (data1.ToArray().SequenceEqual(vardata))
                {
                    finalList.Add(y);
                }                
            });