Как создавать графы вложенных объектов с помощью Linq, когда объекты неизменяемы и ссылаются на своего родителяC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как создавать графы вложенных объектов с помощью Linq, когда объекты неизменяемы и ссылаются на своего родителя

Сообщение Anonymous »

В моей попытке написать больше кода без побочных эффектов (с использованием неизменяемых классов) я наткнулся на кирпичную стену, когда использовал linq для запроса источника данных и выбора родительских и дочерних отношений для создания нового графа, состоящего из неизменяемые объекты.

Проблема возникает, когда у меня есть дочерний объект, например. voiceLineItem, которому в конструкторе должна быть передана ссылка на родительский объект, чтобы свойство .Parent ссылалось на родительский объект, например lineItem[2].Parent ссылается на счет.

Я не понимаю, как это можно сделать с помощью linq, когда классы неизменяемы . Linq и неизменяемые классы — такие большие понятия в C#. Я думаю, что упускаю что-то очевидное.

Я покажу код, демонстрирующий проблему, сначала я покажу использование неизменяемых классов. классов, что, похоже, нет решения с использованием Linq, то ниже я покажу, как это можно сделать с помощью изменяемых классов, чего я, конечно, не хочу делать.

обновление: 17.05.18 Мне трудно поверить, что это невозможно, потому что если это так, то, по моему мнению, это недостаток дизайна языка, и язык находится под довольно пристальным вниманием... гораздо более вероятно, что я просто что-то упускаю.

Пример с неизменяемыми классами (???) — это то, что мне нужно исправить. Как передать ссылку в этот момент на содержащий экземпляр класса?< /strong>

Код: Выделить всё

    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 Items { get; }
public Invoice(int number, IEnumerable 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 изменяемы, и мы можем решить проблему передачи ссылки, сначала создав родительский элемент, затем дочерние элементы, а затем изменение родительского состояния путем присоединения дочерних элементов, которые теперь имеют ссылку на родительский набор. Мне нужно сделать это с помощью неизменяемых классов, но как?[/b]

Код: Выделить всё

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 Items { get; set; }
}

public class Item
{
public Invoice Parent { get; set; }
public int Qty { get; set; }
public string SKU { get; set; }
}
Надеюсь, я пропустил что-то очевидное, любая помощь будет очень признательна.
спасибо
Алан


Подробнее здесь: https://stackoverflow.com/questions/503 ... utable-and
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»