简体   繁体   中英

Map from SQL query (stored procedure) to C# class structure

I have aa stored procedure which returns data in the following format:

public class Sp_Class
{
    public int ItemId { get; set; }

    public int ParentID { get; set; }
}

and it will return the following data:

ItemId-ParentID

1 - NULL

2 - 1

3 - 1

4 - 2

5 - 2

6 - 2

7 - 3

8 - 3

9 - 3

I now want to organise it into the following recursive class structure:

public class MappedStructure
{
    public int ItemId { get; set; }

    public List<MappedStructure> Children { get; set; }
}

Which would put the data into the following format:

    4
2   5
    6       

1

    7
3   8
    9

I know I can write a function to do this, but I feel there should already be tools out there to do this - for example the rest of the project uses entity framework which does this already. I believe this is what an ORM does?

As a note, for this particular query I cannot use Entity, but that is beyond the scope of this discussion.

Here is an example on how to do that using LINQ. First a sampe datatable. I assume that top-level items have a parent ID of Null.

var dataTable = new DataTable();
// Call Sp and fill data in DataTale

A class to represent each item of data:

class Item {

  public Int32 ItemId { get; set; }

  public String Name { get; set; }

  public IEnumerable<Item> Children { get; set; }

}

A function to get the children of a specific item:

IEnumerable<DataRow> GetChildren(DataTable dataTable, Int32 parentId) {
  return dataTable
    .Rows
    .Cast<DataRow>()
    .Where(row => row.Field<Int32>("ParentID") == parentId);
}

A function to create an item including the child collection. This function will recurse down the hierarchy:

Item CreateItem(DataTable dataTable, DataRow row) {
  var id = row.Field<Int32>("ItemId");
  var name = row.Field<String>("Name");
  var children = GetChildren(dataTable, id)
    .Select(r => CreateItem(dataTable, r))
    .ToList();
  return new Item { ItemId = id, Name = name, Children = children };
}

A function to get rows of the top-level items:

IEnumerable<DataRow> GetTopLevelRows(DataTable dataTable) {
  return dataTable
    .Rows
    .Cast<DataRow>()
    .Where(row => row.Field<Int32>("ParentID") == null);
}

Putting it all together:

var items = GetTopLevelRows(dataTable)
  .Select(row => CreateItem(dataTable, row))
  .ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM