The issue here is that the instance of the class "obj" is re-created every time I run through the loop so at the end of the loop, I only have 1 set of the object. It should have several.
foreach (var project in projectsDictionary)
{
foreach (var season in seasonsDictionary)
{
foreach (var episode in episodesDictionary)
{
obj = new Parent
{
Title = project.Value, Link = "1", Children = new List<Parent>
{
new Parent
{
Title = season.Value, Link = "1", Children = new List<Parent>
{
new Parent
{
Title = episode.Value, Link = "1", Children = null
}
}
}
}
};
}
}
}
var responseBody = JsonConvert.SerializeObject(obj);
return responseBody;
public class Parent
{
public string Title
{
get;
set;
}
public string Link
{
get;
set;
}
public List<Parent> Children
{
get;
set;
}
}
Outside the first loop define obj as a list.
var obj = new List<Parent>();
then
obj.Add(new Parent(...));
Related
I am trying to build a data pipeline in .NET. I have been given an xsd and have used the XML Schema Definition Tool to generate C# classes that represent the object model. In order to load this data into my data store I need to transform the data coming out of the XML into structure that matches my application schema and collect/dedupe elements. To do this I have a parser class that will read a file and load the contents into local collections which will then be loaded into my database. I see two options to do this -
Manually loop through the XML with an XmlReader and pull out the data I need, loading it into the local collections in stream. This is not desirable because it does not take advantage of the strongly typed/strict xsd that I was given and requires a lot of hard coding things like while (reader.Read()), check for specific XML nodes, and then `reader.GetAttribute("HardCodedString").
Use XmlSerializer to deserialize the whole file at once and then loop through the deserialized collections and insert into my local collections. This is not desirable because the files could be very large and this method forces me to loop through all of the data twice (once to deserialize and once to extract the data to my local collections).
Ideally I would like some way to register a delegate to be executed as each object is deserialized to insert into my local collections. Is there something in the framework that allows me to do this? Requirements are as follows:
Performant - Only loop through the data once.
Functional - Data is inserted into the local collections during deserialization.
Maintainable - Utilize strongly typed classes that were generated via the xsd.
I have created a minimal example to illustrate my point.
Example XML File:
<Hierarchy xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.example.com/example">
<Children>
<Child ChildId="1" ChildName="First">
<Parents>
<Parent ParentId="1" ParentName="First" RelationshipStart="1900-01-01T00:00:00"/>
<Parent ParentId="2" ParentName="Second" RelationshipStart="2000-01-01T00:00:00"/>
</Parents>
</Child>
<Child ChildId="2" ChildName="Second">
<Parents>
<Parent ParentId="2" ParentName="Second" RelationshipStart="1900-01-01T00:00:00"/>
<Parent ParentId="3" ParentName="Third" RelationshipStart="2000-01-01T00:00:00"/>
</Parents>
</Child>
</Children>
</Hierarchy>
Local collections I am trying to load:
public Dictionary<int, string> Parents { get; }
public Dictionary<int, string> Children { get; }
public List<Relationship> Relationships { get; }
Manual version (not maintainable and doesn't use xsd):
public void ParseFileManually(string fileName)
{
using (var reader = XmlReader.Create(fileName))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Hierarchy")
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Child")
{
int childId = int.Parse(reader.GetAttribute("ChildId"));
string childName = reader.GetAttribute("ChildName");
Children[childId] = childName;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Parent")
{
int parentId = int.Parse(reader.GetAttribute("ParentId"));
string parentName = reader.GetAttribute("ParentName");
DateTime relationshipStart = DateTime.Parse(reader.GetAttribute("RelationshipStart"));
Parents[parentId] = parentName;
Relationships.Add(
new Relationship{
ParentId = parentId,
ChildId = childId,
Start = relationshipStart
});
}
else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "Child")
{
break;
}
}
}
}
}
}
}
}
Deserialize version (loops through the data twice):
public void ParseFileWithDeserialize(string fileName)
{
var serializer = new XmlSerializer(typeof(Hierarchy));
using (var fileStream = new FileStream(fileName, FileMode.Open))
{
var fileData = (Hierarchy) serializer.Deserialize(fileStream);
foreach (var child in fileData.Children)
{
Children[child.ChildId] = child.ChildName;
foreach (var parent in child.Parents)
{
Parents[parent.ParentId] = parent.ParentName;
Relationships.Add(
new Relationship
{
ParentId = parent.ParentId,
ChildId = child.ChildId,
Start = parent.RelationshipStart
});
}
}
}
}
You should use some annotations to get the data from the correct field in the XML, if you use these definitions;
public class Hierarchy
{
public Hierarchy()
{
Children = new List<Child>();
}
public List<Child> Children { get; set; }
}
public class Child
{
public Child()
{
Parents = new List<Parent>();
}
[XmlAttribute("ChildId")]
public int ChildId { get; set; }
[XmlAttribute("ChildName")]
public string ChildName { get; set; }
public List<Parent> Parents { get; set; }
}
public class Parent
{
[XmlAttribute("ParentId")]
public int ParentId { get; set; }
[XmlAttribute("ParentName")]
public string ParentName { get; set; }
[XmlAttribute("RelationshipStart")]
public DateTime RelationshipStart { get; set; }
}
Then you should be able to simplify your code to;
public static Hierarchy Deserialize(string fileName)
{
using (var fileStream = new StreamReader(fileName, Encoding.UTF8))
{
XmlSerializer ser = new XmlSerializer(typeof(Hierarchy));
return (Hierarchy)ser.Deserialize(fileStream);
}
}
To test it out you can create a sample data set and serialize it to a file, then use the above code to read it back
public static void Serialize(Hierarchy h, string fileName)
{
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(Hierarchy));
StreamWriter sw = new StreamWriter(fileName, false, Encoding.UTF8);
ser.Serialize(sw, h);
}
Test Code
static void Test()
{
Hierarchy h = new Hierarchy();
Parent p1 = new Parent() { ParentId = 1, ParentName = "First", RelationshipStart = DateTime.Now };
Parent p2 = new Parent() { ParentId = 2, ParentName = "Second", RelationshipStart = DateTime.Now };
Parent p3 = new Parent() { ParentId = 3, ParentName = "Third", RelationshipStart = DateTime.Now };
Child c1 = new Child() { ChildId = 1, ChildName = "First" };
c1.Parents.Add(p1);
c1.Parents.Add(p2);
Child c2 = new Child() { ChildId = 2, ChildName = "Second" };
c2.Parents.Add(p2);
c2.Parents.Add(p3);
h.Children.Add(c1);
h.Children.Add(c2);
Serialize(h, AppContext.BaseDirectory + "Text.xml");
Hierarchy hReadBack = Deserialize(AppContext.BaseDirectory + "Text.xml");
}
Edit : To answer your question
Use these classes
public class Hierarchy
{
public Hierarchy()
{
Children = new List<Child>();
}
public List<Child> Children { get; set; }
private Dictionary<int, string> _parents;
private Dictionary<int, string> _childrenList;
private List<Relationship> _relationships;
private void CalcuateLists()
{
_parents = new Dictionary<int, string>();
_childrenList = new Dictionary<int, string>();
_relationships = new List<Relationship>();
foreach (Child c in this.Children)
{
if (!_childrenList.ContainsKey(c.ChildId))
{
_childrenList.Add(c.ChildId, c.ChildName);
}
foreach (Parent p in c.Parents)
{
if (!_parents.ContainsKey(p.ParentId))
{
_parents.Add(p.ParentId, p.ParentName);
}
if (_relationships.FirstOrDefault(dat => dat.ParentId == p.ParentId && dat.ChildId == c.ChildId) == null)
{
_relationships.Add(new Relationship() { ChildId = c.ChildId, ParentId = p.ParentId, Start = p.RelationshipStart });
}
}
}
}
public Dictionary<int, string> Parents {
get
{
if (_parents == null)
CalcuateLists();
return _parents;
}
}
public Dictionary<int, string> ChildrenList {
get
{
if (_childrenList == null)
CalcuateLists();
return _childrenList;
}
}
public List<Relationship> Relationships {
get
{
if (_relationships == null)
CalcuateLists();
return _relationships;
}
}
}
public class Child
{
public Child()
{
Parents = new List<Parent>();
}
[XmlAttribute("ChildId")]
public int ChildId { get; set; }
[XmlAttribute("ChildName")]
public string ChildName { get; set; }
public List<Parent> Parents { get; set; }
}
public class Parent
{
[XmlAttribute("ParentId")]
public int ParentId { get; set; }
[XmlAttribute("ParentName")]
public string ParentName { get; set; }
[XmlAttribute("RelationshipStart")]
public DateTime RelationshipStart { get; set; }
}
Then your test code becomes
public static void Test()
{
Hierarchy h = new Hierarchy();
Parent p1 = new Parent() { ParentId = 1, ParentName = "First", RelationshipStart = DateTime.Now };
Parent p2 = new Parent() { ParentId = 2, ParentName = "Second", RelationshipStart = DateTime.Now };
Parent p3 = new Parent() { ParentId = 3, ParentName = "Third", RelationshipStart = DateTime.Now };
Child c1 = new Child() { ChildId = 1, ChildName = "First" };
c1.Parents.Add(p1);
c1.Parents.Add(p2);
Child c2 = new Child() { ChildId = 2, ChildName = "Second" };
c2.Parents.Add(p2);
c2.Parents.Add(p3);
h.Children.Add(c1);
h.Children.Add(c2);
Serialize(h, AppContext.BaseDirectory + "Text.xml");
Hierarchy hReadBack = Deserialize(AppContext.BaseDirectory + "Text.xml");
Dictionary<int, string> Parents = hReadBack.Parents;
Dictionary<int, string> Children = hReadBack.ChildrenList;
List<Relationship> Relationships = hReadBack.Relationships;
}
EDIT
To get the results directly without looping
You will need this class
public class Relationship
{
public int ParentId { get; set; }
public int ChildId { get; set; }
public DateTime Start { get; set; }
}
And this selection
// Get a list of child ids and names
Dictionary<int, string> Children = (from c in hReadBack.Children select new { ChildId = c.ChildId, Name = c.ChildName}).ToDictionary(dat => dat.ChildId, dat => dat.Name);
// Get a parent ids and names
Dictionary<int, string> Parents = (from p in hReadBack.Children.SelectMany(i => i.Parents) select new { ParentId = p.ParentId, Name = p.ParentName }).Distinct().ToDictionary(dat => dat.ParentId, dat => dat.Name);
// Get the relationships
List<Relationship> Relationship = (from Child c in hReadBack.Children from Parent p in c.Parents select new Relationship() { ChildId = c.ChildId, ParentId = p.ParentId, Start = p.RelationshipStart }).ToList();
I have a table in a database which looks like this:
| id | parentID | name |
|----------+----------+-------------|
|ABCD-12345| | Top |
|----------+----------+-------------|
|ABCD-23456|ABCD-12345| Middle |
|----------+----------+-------------|
|ABCD-34567|ABCD-23456| Bottom |
|----------+----------+-------------|
|ABCD-45678|ABCD-23456| Bottom |
etc. - Basically, a hierarchical structure of N depth. I've taken this and shoved it into a datatable.
I have the following class built to hold this data:
public class TreeNode
{
public string id { get; set; }
public string name { get; set; }
public string parentID { get; set; }
public List<TreeNode> children { get; set; }
}
My goal is to go through each of these DataTable rows and insert them into the appropriate location in the TreeNode structure, but I'm super confused as to how I should approach this.
The main point of confusion for me is how I search through the entire existing structure of TreeNodes to see if a node with the parentID exists. Can anyone point me in the right direction?
I tried the following code, but it doesn't work:
public List<TreeNode> BuildTree(int currNode, List<TreeNode> treeList, DataTable dt)
{
foreach(DataRow row in dt.Rows)
{
if(row[1].ToString() == treeList[currNode].id)
{
treeList[currNode].children.Add(new TreeNode
{
id = row[0].ToString(),
name = row[2].ToString(),
parentID = row[1].ToString()
});
dt.Rows.Remove(row);
if(dt.Rows.Count > 0)
{
currNode++;
BuildTree(currNode, treeList, dt);
}
else
{
return treeList;
}
}
}
return null;
}
The problem is this line:
if(row[1].ToString() == treeList[currNode].id)
which gets an out of range exception, because I have a root at index 0, so on the second run (when currNode is 1), it breaks. I need to traverse to treeList[0].Children[int], followed by treeList[0].Children[int].Children[int] and so on and so forth.
So how do I accomplish this goal?
First I'm going to modify the TreeNode class for our convenience. It's not necessary, but just a nice to have. Also I'm going to assume that in your datatable you've done your error checking and there's only one node with ParentId = "".
public class TreeNode
{
public string Id { get; set; }
public string Name { get; set; }
public string ParentID { get; set; }
public List<TreeNode> Children { get; set; }
public TreeNode()
{
Id = Name = ParentID = string.Empty;
Children = new List<TreeNode>();
}
public bool IsRoot { get { return ParentID == string.Empty; } }
public bool IsChild { get { return Children == null || Children.Count == 0; } }
}
First, I'd convert your datatable data into a list of TreeNode objects. Forget about relationships, just create a list with each objects Children being empty. I wrote a method to simulate data retrival from datatable. Instead of that you can use your actual datatable.
static List<DataTableData> GetDataTableData()
{
var data = new List<DataTableData>
{
new DataTableData() { Id = "23456", ParentID = "12345", Name = "Middle" },
new DataTableData() { Id = "55555", ParentID = "12345", Name = "Middle" },
new DataTableData() { Id = "34567", ParentID = "23456", Name = "Bottom" },
new DataTableData() { Id = "12345", ParentID = string.Empty, Name = "Top" },
new DataTableData() { Id = "45678", ParentID = "23456", Name = "Bottom" },
new DataTableData() { Id = "66666", ParentID = "55555", Name = "Bottom" }
};
return data;
}
And this is what your Main() would look like:
static void Main(string[] args)
{
var treeNodes = new List<TreeNode>();
var dataTable = GetDataTableData();
foreach (var data in dataTable)
{
treeNodes.Add(new TreeNode() { Id = data.Id, Name = data.Name, ParentID = data.ParentID });
}
var root = BuildTree(treeNodes);
Console.ReadLine();
}
Now, in my BuildTree() method, instead of passing the datatable I can pass my TreeNode list, and return just the root node.
public static TreeNode BuildTree(List<TreeNode> nodes)
{
foreach (var node in nodes)
{
node.Children = nodes.Where(x => x.ParentID == node.Id).ToList();
}
return nodes.Find(x => x.IsRoot);
}
BuildTree() Breakdown
The nodes list already have all the nodes corresponding to data in your datatable. The BuildTree() is merely going to create the parent-child relations and fill in each object's Children list.
So I iterate through the list, and see what other elements in the list are supposed to be its children. When you have iterated through the list you'd created all the parent-child relationships. Finally, I pick the root node (the one who's ParentId is empty) and return it.
Edit
Here's an easy method to print and verify your tree.
static void PrintTree(TreeNode node, int indents)
{
for (int tab = 0; tab < indents; tab++)
{
Console.Write("\t");
}
Console.WriteLine("{0} - {1}", node.Id, node.Name);
if (node.Children != null && node.Children.Count > 0)
{
indents++;
foreach (var child in node.Children)
{
PrintTree(child, indents);
}
}
}
My output looks like this:
If you are building a class structure then you need a class with a recursive method. Not sure how efficient this will be if it gets too big. Execute the method from the top of the tree.
public class TreeNode
{
public string id { get; set; }
public string name { get; set; }
public string parentID { get; set; }
public List<TreeNode> children { get; set; }
public TreeNode() {
children = new List<TreeNode>();
}
public TreeNode FindParentWithID(string ID)
{
TreeNode ParentWithID = null;
//check my parentID if i am the one being looked for then return
if (id == ID) return this;
//search children
foreach (TreeNode treeNode in children)
{
ParentWithID = treeNode.FindParentWithID(ID);
if (ParentWithID != null)
{
break;
}
}
return ParentWithID;
}
}
You would load your data into the classes from the database. I had to hard code the values for the example to work:
TreeNode treeNode5 = new TreeNode() { id = "ABCD-12345", parentID = null, name = "Top" };
TreeNode treeNode6 = new TreeNode() { id = "ABCD-12346", parentID = "ABCD-12345", name = "Middle" };
treeNode5.children.Add(treeNode6);
TreeNode treeNode7 = new TreeNode() { id = "ABCD-12347", parentID = "ABCD-12346", name = "Bottom" };
TreeNode treeNode8 = new TreeNode() { id = "ABCD-12348", parentID = "ABCD-12346", name = "Bottom" };
treeNode6.children.Add(treeNode7);
treeNode6.children.Add(treeNode8);
TreeNode topOne = treeNode5.FindParentWithID("ABCD-12346");
topOne will be end up being treeNode6 name="Middle" in this example.
try this code, i have same issue and it works perfectly
this method used to build tree from list of items, by looping through all items, and add each item to its parent's child list. and return only the root item with its nested child.
public TreeNode BuildTree(List<TreeNode> source)
{
// build the children list for each item
foreach (var item in source)
{
var itm = source.Where(i => i.parentID == item.Id).ToList();
item.ChildItems = itm;
}
// return only the root parents with its child inside
return source.Where(i => i.parentID == null).FirstOrDefault();
}
noting that this method return only on TreeNode Object with its child, you can return List by changing .FirstOrDefault() to .ToList() in return line
I have following table:
---------------------
Id Title Parent
---------------------
1 Parent NULL
2 Level_1 1
3 Level_2 1
4 Level_3 1
5 Level NULL
6 Level_New 5
Now I want to display these data in my console application, I know I need a recursive function but no idea how to do it becuase I want to read these data using ADO.NET not EntityFramework.In EF I could define a model that has a navigation property for children:
public class Menu
{
public int Id { get; set; }
public string Title { get; set; }
public int? Parent { get; set; }
public ICollection<Menu> Children { get; set; }
}
But the problem is that I don't want to use EF. I want to do it using raw ADO.NET
Recursion isn't fun, this is a solution that I used to test for a much larger recursion
public class MyObject
{
public string Id;
public string ParentId;
public string Name;
public string Comments;
}
a lot of this code you wont need, but this should give you want you need on recursion.
private void BindTree(IEnumerable<MyObject> list, TreeNode parentNode, string previousNode)
{
var myObjects = list as IList<MyObject> ?? list.ToList();
var nodes = myObjects.Where(x => (parentNode == null ? x.ParentId == "[].[].[(root)]" : x.ParentId == parentNode.Value));
var listOfNodeNames = new List<string>();
foreach (var node in nodes)
{
var newNode = new TreeNode(node.Name, node.Id);
BindTree(myObjects, newNode, previousNode);
}
}
The above code does the recursion I need ( code you wont need stripped out ) and builds a treeview on a page based on data from a datatable.
But, this should give you want you need to do your recursion.
You need to pull data from server first, then construct tree on client side. Beware of circular reference.
First, change your Menu class to ensure that Children will never null
public class Menu
{
public Menu()
{
Children = new HashSet<Menu>();
}
public int Id { get; set; }
public string Title { get; set; }
public int? Parent { get; set; }
public ICollection<Menu> Children { get; private set; }
}
Then pull the data from database, and construct the tree
var connBuilder = new SqlConnectionStringBuilder();
connBuilder.DataSource = "localhost";
connBuilder.InitialCatalog = "YourDatabaseName";
connBuilder.IntegratedSecurity = true;
using (var con = new SqlConnection(connBuilder.ToString()))
{
con.Open();
var list = new List<Menu>();
//pull data from database
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT Id, Title, Parent FROM [dbo].[YourTableName]";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(new Menu
{
Id = reader.GetInt32(0),
Title = reader.GetString(1),
Parent = reader.IsDBNull(2) ?(int?) null : reader.GetInt32(2)
});
}
}
}
//construct tree
var newList = new List<Menu>();
foreach (var l1 in list)
{
if (l1.Parent == null)
{
newList.Add(l1);
}
foreach (var l2 in list)
{
if (l2.Parent == l1.Id)
{
l1.Children.Add(l2);
}
}
}
// do whatever you want with newList
}
You will get data like this
I have following classes:-
public class SiteMapSection
{
public string sectionUrl { get; set; }
public List<SiteMapSubSection> subSection { get; set; }
}
public class SiteMapSubSection
{
public string subSectionUrl { get; set; }
public List<SiteMapArticle> article { get; set; }
}
public class SiteMapArticle
{
public string url { get; set; }
}
I'm using SiteMapSection class as a Type in the list:-
List<SiteMapSection> siteMapSection = new List<SiteMapSection>();
Now, i'm trying to add items in 'siteMapSection' list, as given below:-
foreach (var section in sections)
{
.....
siteMapSection.Add(new SiteMapSection { sectionUrl = section.Url });
.....
foreach (var subsection in subsections)
{
.....
siteMapSection.Add(new SiteMapSubSection { ??stuck_here?? });
.....
var articles = GetNextArticles(0, subSectionId, true, false);
.....
foreach(var article in articles)
{
siteMapSection.Add(new SiteMapArticle { ??stuck_here?? });
}
}
}
How do I iterate through the collection and add items in List siteMapSection.
Updated Code, this also not works i see only siteMapSection.Add(sms) item got added but other nested still empty
List<SiteMapSection> siteMapSection = new List<SiteMapSection>();
SectionArticle sa = new SectionArticle();
foreach (BE.Section section in Sections.Find(websiteId, parentSectionId))
{
int sectionId = section.Id;
var sms = new SiteMapSection();
sms.sectionUrl = Sections.VirtualPath(section) + ".aspx";
var _subsections = new List<SiteMapSubSection>();
foreach (BE.Section subsection in Sections.Find(websiteId, sectionId))
{
int subSectionId = subsection.Id;
var smss = new SiteMapSubSection();
smss.subSectionUrl = Sections.VirtualPath(subsection) + ".aspx";
var articles = sa.GetArticlesForSection(websiteId, subSectionId, 10);
var _articles = new List<SiteMapArticle>();
foreach (var article in articles)
{
var sma = new SiteMapArticle();
sma.url = article.Code + ".aspx";
_articles.Add(sma);
}
_subsections.Add(smss);
}
siteMapSection.Add(sms);
}
I just realized that you are trying to add different types to List<SiteMapSection>. You can not add different types to a generic list. When creating a list you are defining the types which are allowed in the list, where as you are trying to add different types.
You need to change
siteMapSection.Add(new SiteMapSubSection { ??stuck_here?? });
to
siteMapSection.Add(new SiteMapSection { ??stuck_here?? });
If you provide a bit more context perhaps we could give you a better approach in general.
Hope this helps.
foreach (var section in sections)
{
.....
var sms = new SiteMapSection { sectionUrl = section.Url };
sms.subSection = new List<SiteMapSubSection>();
.....
foreach (var subsection in subsections)
{
.....
var smss = new new SiteMapSubSection { subsection }
ssms.article = new List<SiteMapArticle>();
.....
var articles = GetNextArticles(0, subSectionId, true, false);
.....
foreach(var article in articles)
{
smss.article.Add(new SiteMapArticle { article });
}
sms.subSection.Add(ssms);
}
siteMapSection.Add(sms);
}
public class parent
{
public string abc { get; set; }
public childclass pos { get; set; }
}
public class childclass
{
public string value { get; set; }
}
I am currently reading the collection of parent class
var obj =
(from dia in parent
select new
{
abc = dia.abc,
pos = new childclass()
{
value = dia.pos.value
},
})
.ToList();
how do I read the nested class childclass using linq to object , this piece is not working
pos = new childclass()
{
Value = dia.pos.Value
},
Please advise
It works perfectly, I think your problem is case sensitive
Classes:
public class Parent
{
public string Abc { get; set; }
public Childclass Pos { get; set; }
}
public class Childclass
{
public string Value { get; set; }
}
Use:
var parent = new List<Parent> {
new Parent { Abc = "abc1", Pos = new Childclass { Value = "Value1" } },
new Parent { Abc = "abc2", Pos = new Childclass { Value = "Value2" } }
};
var obj =(from dia in parent select new {
abc = dia.Abc,
pos = new Childclass()
{
Value = dia.Pos.Value
},
}).ToList();
C# is case-sensitive. The value field in your class childClass has a lower-case 'v'. Your LINQ statement is referencing it using an upper-case 'V'.
Try the following code:
var obj = (from dia in parent
select new
{
abc = dia.abc,
pos = new childclass()
{
value = dia.pos.value // 'Value' has been changed to 'value'
},
}).ToList();
Here is a test I ran to verify that the updated LINQ statement works:
var parents = new List<parent>()
{
new parent{abc = "abc", pos = new childclass{ value = "value" }}
};
var obj =
(from dia in parents // changed to 'parents' to match my variable above
select new
{
abc = dia.abc,
pos = new childclass()
{
value = dia.pos.value
},
}).ToList();
foreach (var par in obj)
{
Console.WriteLine(par);
}
The resulting output was:
"{ abc = abc, pos = ProgrammingTestBed.Program+childclass }"