В моей попытке написать больше кода без побочных эффектов (используя неизменяемые классы) я столкнулся с кирпичной стеной, когда использовал linq для запроса источника данных и выбирал родительские и дочерние отношения, чтобы создать новый граф, состоящий из неизменяемые объекты.
Проблема вступает в игру, когда у меня есть дочерний объект, например Объект invoiceLineItem, которому необходимо иметь ссылку на родительский объект, переданный ему в его конструкторе, чтобы свойство .Parent
ссылалось на родительский объект, например, lineItem[2].Parent
ссылается на Invoice
.
Я не вижу, как это можно сделать с помощью linq, когда классы неизменны. Linq и неизменяемые классы - это такие большие понятия в C #, я думаю, что мне не хватает чего-то очевидного.
Я покажу некоторый код, который демонстрирует проблему, сначала я покажу с помощью неизменяемых классов, что, по-видимому, нет решения с использованием Linq, затем ниже я покажу, как вы можете это сделать с помощью изменяемых классов, что, конечно, я делаю не хочу делать.
обновление: 17.05.18 Мне трудно поверить, что это невозможно, потому что если это так, то, по моему мнению, это недостаток дизайна в языке, и язык находится под довольно пристальным вниманием, ... гораздо больше скорее всего, я просто что-то упускаю.
Пример с неизменяемыми классами (???) - это то, что мне нужно исправить, как передать ссылку в этот момент в содержащий экземпляр класса?
void Main()
{
var nums = new[]{
new { inv = 1, lineitems =new [] {new { qty = 1, sku = "a" }, new { qty = 2, sku = "b" }}},
new { inv = 2, lineitems =new [] { new { qty = 3, sku = "c" }, new { qty = 4, sku = "d" }}},
new { inv = 3, lineitems =new [] { new { qty = 5, sku = "e" }, new { qty = 5, sku = "f" }}}
};
// How do I pass in the reference to the newly being created Invoice
// below to the Item constructor?
var invoices = nums.Select(i =>
new Invoice(i.inv, i.lineitems.Select(l =>
new Item(l.qty, l.sku, ??? )
)));
invoices.Dump();
}
public class Invoice
{
public int Number { get; }
public IEnumerable<Item> Items { get; }
public Invoice(int number, IEnumerable<Item> items) {
Number = number;
Items = items;
}
}
public class Item
{
public Invoice Parent { get; }
public int Qty { get; }
public string SKU { get; }
public Item(int qty, string sku, Invoice parent) {
Parent = parent;
Qty = qty;
SKU = sku;
}
}
Те же классы, но на этот раз DTO изменчивы, и мы можем решить передачу ссылки, сначала создав родителя, затем потомков, затем изменив состояние родителя, присоединив потомков, которые теперь имеют ссылка на родительский набор. Я должен быть в состоянии сделать это, используя неизменяемые классы, но как?
void Main()
{
var nums = new[]{
new { inv = 1, lineitems =new [] {new { qty = 1, sku = "a" }, new { qty = 2, sku = "b" }}},
new { inv = 2, lineitems =new [] { new { qty = 3, sku = "c" }, new { qty = 4, sku = "d" }}},
new { inv = 3, lineitems =new [] { new { qty = 5, sku = "e" }, new { qty = 5, sku = "f" }}}
};
var invoices = nums.Select(i =>
{
var invoice = new Invoice()
{
Number = i.inv
};
var items = from item in i.lineitems select new Item()
{
Parent = invoice, Qty = item.qty, SKU = item.sku
};
invoice.Items = items;
return invoice;
});
invoices.Dump();
}
public class Invoice
{
public int Number { get; set; }
public IEnumerable<Item> Items { get; set; }
}
public class Item
{
public Invoice Parent { get; set; }
public int Qty { get; set; }
public string SKU { get; set; }
}
Я надеюсь, что упустил что-то очевидное, любая помощь будет наиболее ценной.
благодарю вас
Alan