List Generate hierarchy number - c#

I'd like to make a method to generate a hierarchy by ParentId
This is my Db class :
public class Kart
{
public long Id { get; set; }
public long? ParentId { get; set; }
public string Name { get; set; }
}
and my Model Class
public class KartModel
{
public long Id { get; set; }
public long? ParentId { get; set; }
public string Hierarchy { get; set; }
public string Name { get; set; }
}
I don't store Hierarchy column in db.
I would like to set Hierarchy property by ParentId like
1
1.1
1.1.1
1.1.2
1.1.3
1.2
1.3
1 //(if ParentId == null start 1)
1.1
Thanks.
Edit: ParentId references itself (Kart)

Recursive methods are the simplest way to set up hierarchical structures. The code below is a console application that generates the hierarchy so that you asked.
class Program
{
public class Kart
{
public long Id { get; set; }
public long? ParentId { get; set; }
public string Name { get; set; }
}
public class KartVM
{
public long Id { get; set; }
public long? ParentId { get; set; }
public string Hierarchy { get; set; }
public string Name { get; set; }
}
static void Main(string[] args)
{
List<Kart> list = new List<Kart>
{
new Kart {Id = 1, ParentId = null, Name = "Main Content1"},
new Kart {Id = 2, ParentId = 1, Name = "Main Content1"},
new Kart {Id = 3, ParentId = 1, Name = "Main Content1"},
new Kart {Id = 4, ParentId = 1, Name = "Main Content1"},
new Kart {Id = 5, ParentId = 3, Name = "Main Content1"},
new Kart {Id = 6, ParentId = 3, Name = "Main Content1"},
new Kart {Id = 7, ParentId = 4, Name = "Main Content1"},
new Kart {Id = 8, ParentId = 4, Name = "Main Content1"},
new Kart {Id = 9, ParentId = 8, Name = "Main Content1"},
new Kart {Id = 10, ParentId = 8, Name = "Main Content1"},
new Kart {Id = 11, ParentId = 8, Name = "Main Content1"},
new Kart {Id = 12, ParentId = 11, Name = "Main Content1"},
new Kart {Id = 13, ParentId = 11, Name = "Main Content1"},
new Kart {Id = 14, ParentId = 13, Name = "Main Content1"},
new Kart {Id = 15, ParentId = null, Name = "Main Content1"},
new Kart {Id = 16, ParentId = 15, Name = "Main Content1"},
new Kart {Id = 17, ParentId = 16, Name = "Main Content1"},
new Kart {Id = 18, ParentId = 17, Name = "Main Content1"},
new Kart {Id = 19, ParentId = 18, Name = "Main Content1"},
};
List<KartVM> theResult = new List<KartVM>();
GetHierachicalList(list, theResult, null, "");
foreach(KartVM t in theResult)
{
Console.WriteLine(t.Hierarchy);
}
Console.ReadLine();
}
static void GetHierachicalList(List<Kart> kart, List<KartVM> kartVM, Kart currentNode, string curH)
{
List<Kart> tmp = new List<Kart>();
if (currentNode == null)
tmp = kart.Where(c => c.ParentId == null).ToList();
else
tmp = kart.Where(c => c.ParentId == currentNode.Id).ToList();
int count = 1;
foreach(Kart k in tmp)
{
KartVM tmpVM = new KartVM { Id = k.Id, Name = k.Name, ParentId = k.ParentId };
tmpVM.Hierarchy += curH + "." + count.ToString();
if (tmpVM.Hierarchy.StartsWith("."))
tmpVM.Hierarchy = tmpVM.Hierarchy.Remove(0, 1);
kartVM.Add(tmpVM);
count++;
GetHierachicalList(kart, kartVM, k, tmpVM.Hierarchy);
}
}
}
In this case , the method is recursive GetHierachicalList
To run it make the call as follows:
GetHierachicalList(list, theResult, null, "")
Hope this helps.

Related

Using Moq with Entity Framework 6 - Mocking Include and Where

I'm trying to create some In-Memory dbContext mocks using Moq and using EntityFramework.Testing.Moq extension methods:
https://github.com/scott-xu/EntityFramework.Testing
I'm hitting a brick wall when I'm trying to unit test my eagerly loaded queries using mocked context. The issue is, nothing is selected at all. I know something should be selected, because when I point the same query using LINQPad to my source database, I get the 2 results back that I expect.
I never know how much code etc I need to post, so hopefully the below will help.
Data Diagram
I have two main tables, dbo.Applicant that holds basically user details and dbo.Application, which holds job applications, there are lookup tables that dbo.Application hooks into:
Example Models
This is a code first approach based off the above diagram. I have removed properties to keep the code as clean and to the point for the question:
[Table("Application")]
public partial class Application
{
[Min(1)]
public int Id { get; set; }
[Required]
[StringLength(50)]
public string ApplicationId { get; set; }
[Min(1)]
public int ApplicantId { get; set; }
public virtual Applicant Applicant { get; set; }
}
[Table("Applicant")]
public partial class Applicant
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Applicant()
{
Applications = new HashSet<Application>();
RowStatus = "L";
}
public int Id { get; set; }
[Required]
public string FullName { get; set; }
[Required]
public string AddressLine1 { get; set; }
[Required]
public string Email { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Application> Applications { get; set; }
}
Context
Again a cut down context, but just in case I'm ask for it in the comments:
public partial class WorkExperienceContext : DbContext
{
public WorkExperienceContext()
: base("name=WorkExperienceContext")
{
this.Configuration.LazyLoadingEnabled = false;
}
public WorkExperienceContext(string userTestConnectionString)
: base(userTestConnectionString)
{
Trace.Write("Using test context " + Add to dictionary);
}
public virtual DbSet<Applicant> Applicants { get; set; }
public virtual DbSet<Application> Applications { get; set; }
}
Unit Test method
The following is (again) a cut down version of the Unit test method where I expect two Application records to be pulled through based off the email.
As you can see from the below, there are:
2 Application records for Lucifer (ApplicantId = 666)
There is one Applicant record with an email of misunderstood#fireandbrimestone.co.uk
My issue is test is null, when querying the database itself with the same code, I get the correct results. I'm perplexed what I need to do. Remember I'm using the EntityFramework.Testing.Moq.SetupData() method which handles the mocking of the DbSet methods and transforming the List<> seed data to an IQueryable collection.
public void InMemory_Find_Application_By_Email_EFMoq()
{
var applications = new List<Application>
{
new Application { Id = 1, ApplicantId = 666, ApplicationId = "1-a", DivisionId = 2, PublishingAreaId = 4, SourceId = 2, SkillsLearnt = "How to pick up pen", RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2, CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay } ,
new Application { Id = 2, ApplicantId = 666, ApplicationId = "1-a", DivisionId = 3, PublishingAreaId = 4, SourceId = 2, SkillsLearnt = "How to pick up pen", RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2,CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay } ,
new Application { Id = 3, ApplicantId = 5, ApplicationId = "1-b", DivisionId = 3, PublishingAreaId = 1, SourceId = 2, SkillsLearnt = "Reading a book well" , RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2,CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay } ,
new Application { Id = 4, ApplicantId = 5, ApplicationId = "1-b", DivisionId = 2, PublishingAreaId = 1, SourceId = 2, SkillsLearnt = "Reading a book well ", RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2 ,CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay } ,
new Application { Id = 5, ApplicantId = 5, ApplicationId = "1-b", DivisionId = 7, PublishingAreaId = 1, SourceId = 2, SkillsLearnt = "Reading a book well" , RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2 ,CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay } ,
new Application { Id = 6, ApplicantId = 24, ApplicationId = "1-c", DivisionId = 10, PublishingAreaId = 3, SourceId = 1, SkillsLearnt = "I can now re-iterate stuff", RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2,CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay },
new Application { Id = 7, ApplicantId = 21, ApplicationId = "1-d", DivisionId = 2, PublishingAreaId = 2, SourceId = 1, SkillsLearnt = "I made some bread the other day", RowStatus="L", ApplicantStartDateId = 1,
ApplicantDisabilityId = 2 ,CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay }
};
var applicants = new List<Applicant>
{
new Applicant {Id = 5, FullName = "Pen Is", AddressLine1="Somewhere Over the Rainbow", County="West Sussex", Email="pen_is#hotmail.co.uk", RowStatus = "L",
GenderId = 2, EducationId = 1, CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay, PostCode="PEN 1ST", Telephone="N/A"},
new Applicant {Id = 24, FullName = "Gareth Bradley", AddressLine1="an address", County="West Sussex", Email="gareth.bradley#hachette.co.uk", RowStatus = "L",
GenderId = 2, EducationId = 1, CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay, PostCode="bn13 3qb",Telephone="N/A"} ,
new Applicant {Id = 21, FullName = "Lizzy Windsor", AddressLine1="A Palace (Take your pick)", County="Berkshire", Email="HerRoyalMaj#TheCrownJewels.co.uk", RowStatus = "L",
GenderId = 2, EducationId = 1, CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay, PostCode="BE1 1HM",Telephone="N/A"} ,
new Applicant {Id = 666, FullName = "Lucifer MorningStar", AddressLine1="Hotsy Street", County="Down South", Email="misunderstood#fireandbrimes1one.co.uk" , RowStatus = "L",
GenderId = 3, EducationId = 1, CreatedDate = DateTime.Now, CreatedTime = DateTime.Now.TimeOfDay, PostCode="HE11 6SS",Telephone="666-666"}
};
foreach (Applicant applicant in applicants)
{
applicant.Applications = applications.Where(a => a.ApplicantId == applicant.Id).ToArray();
}
foreach (Application application in applications)
{
application.Applicant = applicants.SingleOrDefault(a => a.Id == application.ApplicantId);
}
var mockSet = new Mock<DbSet<Application>>()
.SetupData(applications);
var mockSetUsers = new Mock<DbSet<Applicant>>()
.SetupData(applicants);
var mockContext = new Mock<WorkExperienceContext>();
mockContext.Setup(c => c.Applications).Returns(mockSet.Object);
mockContext.Setup(c => c.Applicants).Returns(mockSetUsers.Object);
var mockService = new WorkExperienceFormService(mockContext.Object);
var test = mockContext.Object
.Applications
.Include(a => a.Applicant)
.Where(e => e.Applicant.Email == "misunderstood#fireandbrimestone.co.uk")
.ToList();
Assert.AreEqual(2, test.Count());
}
The following is proof of my LINQPad is pulling the data without a mocked context:
Maybe it's a typo when you posted the code, but the e-mail for 'Lucifer MorningStar' is
misunderstood#fireandbrimes1one.co.uk instead of
misunderstood#fireandbrimestone.co.uk

Seeding the database in Entity Framework

When I try to fill seed in my database I got an error:
The entity found was of type PetsOwner_FF460419E950312585B2229EA7AA6AEAA692190083B7EA5830FB08DEEE79E35D when an entity of type Caretaker was requested."
I went through all tips which I found, I examined the relation between classes and didn't find any solution.
context.CareTakers.AddOrUpdate(c => c.Id,
new Caretaker { Id = 1, Name = "Jan", Surname = "Nowak", Pesel = "29032400352", BankAccountNumber = "05 8202 1016 5582 6188 2074 1719", PhoneNumber = "666-449-292", Accomodations = new List<Accommodation> { context.Accomodations.Find(1) } },
new Caretaker { Id = 2, Name = "Anna", Surname = "Kowalski", Pesel = "29010209388", BankAccountNumber = "76 1610 1335 0163 2600 0322 4138", PhoneNumber = "789-335-709", Accomodations = new List<Accommodation> { context.Accomodations.Find(2) } },
new Caretaker { Id = 3, Name = "Sylwia", Surname = "Boski", Pesel = "42022605090", BankAccountNumber = "21 8499 0008 3163 0216 0506 9685", PhoneNumber = "538 -887-645", Accomodations = new List<Accommodation> { context.Accomodations.Find(3) } },
new Caretaker { Id = 4, Name = "Zbigniew", Surname = "Ryba", Pesel = "10262717572", BankAccountNumber = "61 9614 0008 9550 1997 2431 0213", PhoneNumber = "795-200-495", Accomodations = new List<Accommodation> { context.Accomodations.Find(4) } }
);
context.Accomodations.AddOrUpdate(a => a.Id,
new Accommodation { Id = 1, Beginning = new DateTime(2016, 1, 2), End = new DateTime(2016, 1, 3), PricePerDay = 10.5, Pet = context.Pets.Find(1), Caretaker = context.CareTakers.Find(1) },
new Accommodation { Id = 2, Beginning = new DateTime(2015, 2, 3), End = new DateTime(2016, 2, 4), PricePerDay = 100.0, Pet = context.Pets.Find(2), Caretaker = context.CareTakers.Find(2) },
new Accommodation { Id = 3, Beginning = new DateTime(2014, 9, 10), End = new DateTime(2016, 9, 11), PricePerDay = 12.3, Pet = context.Pets.Find(3), Caretaker = context.CareTakers.Find(3) },
new Accommodation { Id = 4, Beginning = new DateTime(2013, 11, 12), End = new DateTime(2016, 12, 13), PricePerDay = 41.4, Pet = context.Pets.Find(4), Caretaker = context.CareTakers.Find(4) }
);
My classes look like:
public class Accommodation {
public int Id { get; set; }//{BAG}
public virtual Caretaker Caretaker { get; set; }
public virtual Pet Pet { get; set; }
public double PricePerDay { get; set; }
public DateTime Beginning { get; set; }
public DateTime End { get; set; }
public double TotalPrice {
get {
return (End - Beginning).Days * PricePerDay;
}
}
}
[Table("Caretakers")]
public class Caretaker : Person {
public static int Percent => 20;//C# 6
public DateTime ObtainedLicense { get; set; }
public DateTime Hired { get; set; }
public double Salary => 0;
public virtual ICollection<Surgery> Surgeries { get; set; }
public virtual Vet Superior { get; set; }//rekurencyjna
//pochodny
public int AnimalsCurrentlyCareTaken => 0;//Lambda do wyliczenia ilosci opiekowaniymi sie zwierzetyami
public virtual ICollection<Accommodation> Accomodations { get; set; }
}

How would I pivot this object using linq?

If I have the following objects.
public class CFS
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public IList<Topic> Topics { get; set; }
public IList<Status> Status { get; set; }
}
public class Topic
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Status
{
public int ID { get; set; }
public string Name { get; set; }
}
How can I put it into the following object where Topic.ID == Status.ID && Status.Name = "pass"? The Topic and Status string values would be the Topic.Name and Status.Name values respectively. The list of string can be the FirstName, email, whatever, that part is trivial. I realize Topic and Status expose the same properties but that's just for this example.
public class SelectedTopic
{
public string Topic { get; set; }
public string Status { get; set; }
public IList<string> Person { get; set; }
}
I've tried several combinations of SelectMany, Any, Join and I can't seem to pivot the data the way I want.
I don't know why you would want to do this but here is how:
void Main()
{
List<Topic> topicA = new List<Topic>() { new Topic() { ID = 1, Name = "1" }, new Topic() {ID = 2 , Name = "2"}, new Topic() {ID = 3, Name = "3" } };
List<Topic> topicB = new List<Topic>() { new Topic() { ID = 2, Name = "2" }, new Topic() {ID = 3 , Name = "3"}, new Topic() {ID = 4, Name = "4" } };
List<Topic> topicC = new List<Topic>() { new Topic() { ID = 1, Name = "1" } };
List<Topic> topicD = new List<Topic>() { new Topic() {ID = 2 , Name = "2"}, new Topic() {ID = 3, Name = "3" } };
List<Status> statusA = new List<Status>() { new Status() { ID = 1, Name = "pass" }, new Status() {ID = 2 , Name = "2"}, new Status() {ID = 3, Name = "3" } };
List<Status> statusB = new List<Status>() { new Status() { ID = 2, Name = "2" }, new Status() {ID = 3 , Name = "pass"}, new Status() {ID = 4, Name = "pass" } };
List<Status> statusC = new List<Status>() { new Status() { ID = 1, Name = "pass" } };
List<Status> statusD = new List<Status>() { new Status() {ID = 2 , Name = "2"}, new Status() {ID = 3, Name = "pass" } };
List<CFS> test = new List<CFS>() {
new CFS() { FirstName = "A", LastName = "A", Email = "A#A.com", Topics = topicA, Status = statusA },
new CFS() { FirstName = "B", LastName = "B", Email = "B#B.com", Topics = topicB, Status = statusB },
new CFS() { FirstName = "C", LastName = "C", Email = "C#C.com", Topics = topicC, Status = statusC },
new CFS() { FirstName = "D", LastName = "D", Email = "D#D.com", Topics = topicD, Status = statusD },
};
var result = test.SelectMany(x => x.Topics.SelectMany((t) => x.Status, (topic,status) => new { CFS = x, T = topic, S = status }))
.Where(x => x.S.Name == "pass" && x.T.ID == x.S.ID)
.Select(x => new { first = x.CFS.FirstName, status = x.S.Name, topic = x.T.Name})
.GroupBy(x => x.topic)
.Select(x => new SelectedTopic { Topic = x.Key, Status = "pass", Person = x.Select(z => z.first).Distinct().ToList() })
.Dump();
}
Tested in LinqPad -- if you are not using this tool I suggest you do so.

How to setup with navigation properties

I am trying to set up a simple library application in MVC4
I have the following entities
public class Book
{
public Book()
{
BorrowedBooks = new List<BorrowedBooks>();
}
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public virtual ICollection<BorrowedBooks> BorrowedBooks { get; set; }
}
public class Borrower
{
public Borrower()
{
BorrowedBooks = new List<BorrowedBooks>();
}
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public virtual ICollection<BorrowedBooks> BorrowedBooks { get; set; }
}
public class BorrowedBooks
{
public int Id { get; set; }
public int BookId { get; set; }
public int BorrowerId { get; set; }
public DateTime DateBorrowed { get; set; }
public virtual Book Book { get; set; }
public virtual Borrower Borrower { get; set; }
}
I have setup 2 repositories
public class BookRepository : IBookRepository
{
private List<Book> books = new List<Book>
{
new Book { Id = 1, Title = "Queen of the road", Author = "Tricia Stringer", BorrowedBooks = new List<BorrowedBooks>{ new BorrowedBooks {BookId = 1, BorrowerId = 1, DateBorrowed = DateTime.Parse("26/03/2014")}} },
new Book { Id = 2, Title = "Don't look now", Author = "Paul Jennings" },
new Book { Id = 3, Title = "Too bold to die", Author = "Ian McPhedran" },
new Book { Id = 4, Title = "The rosie project", Author = "Graeme Simson" },
new Book { Id = 5, Title = "In great spirits", Author = "Archie Barwick" },
new Book { Id = 6, Title = "The vale girl", Author = "Nelika Mcdonald" },
new Book { Id = 7, Title = "Watching you", Author = "Michael Robotham" },
new Book { Id = 8, Title = "Stillways", Author = "Steve Bisley" },
};
private List<BorrowedBooks> borrowedBooks = new List<BorrowedBooks>
{
new BorrowedBooks {BookId = 8, Book = new Book { Id = 8, Title = "Stillways", Author = "Steve Bisley" }, BorrowerId = 2, DateBorrowed = DateTime.Parse("01/04/2014")},
new BorrowedBooks {BookId = 6, BorrowerId = 4, DateBorrowed = DateTime.Parse("08/04/2014")},
new BorrowedBooks {BookId = 2, BorrowerId = 4, DateBorrowed = DateTime.Parse("08/04/2014")},
new BorrowedBooks {BookId = 1, BorrowerId = 1, DateBorrowed = DateTime.Parse("26/03/2014")},
};
public IEnumerable<Book> Search()
{
return books;
}
}
public class BorrowerRepository : IBorrowerRepository
{
private List<Borrower> borrowers = new List<Borrower>
{
new Borrower { Id = 1, Firstname = "John", Lastname = "Smith" },
new Borrower { Id = 2, Firstname = "Mary", Lastname = "Jane" },
new Borrower { Id = 3, Firstname = "Peter", Lastname = "Parker" },
new Borrower { Id = 4, Firstname = "Eddie", Lastname = "Brock" },
};
public void Add(Borrower borrower)
{
this.borrowers.Add(borrower);
}
}
How do I link the properties together? ie in my BorrowerRepository search method, it return all the data, but the Book value is just an ID, how do I link it with the values from the book repository?
have I set up my navigation property wrong? or is it the way I have set up my Repository data?
One way to achieve that is to add a static class to hold collections of your data in memory.
Then in each of your repositories you delegate any data related operation to the appropriate collections in the data store and you can use Linq to do your queries.
public static class DataStore
{
private static List<Book> books = new List<Book>
{
new Book { Id = 1, Title = "Queen of the road", Author = "Tricia Stringer", BorrowedBooks = new List<BorrowedBooks>{ new BorrowedBooks {BookId = 1, BorrowerId = 1, DateBorrowed = DateTime.Parse("26/03/2014")}} },
new Book { Id = 2, Title = "Don't look now", Author = "Paul Jennings" },
new Book { Id = 3, Title = "Too bold to die", Author = "Ian McPhedran" },
new Book { Id = 4, Title = "The rosie project", Author = "Graeme Simson" },
new Book { Id = 5, Title = "In great spirits", Author = "Archie Barwick" },
new Book { Id = 6, Title = "The vale girl", Author = "Nelika Mcdonald" },
new Book { Id = 7, Title = "Watching you", Author = "Michael Robotham" },
new Book { Id = 8, Title = "Stillways", Author = "Steve Bisley" },
};
private static List<BorrowedBooks> borrowedBooks = new List<BorrowedBooks>
{
new BorrowedBooks {BookId = 8, Book = new Book { Id = 8, Title = "Stillways", Author = "Steve Bisley" }, BorrowerId = 2, DateBorrowed = DateTime.Parse("01/04/2014")},
new BorrowedBooks {BookId = 6, BorrowerId = 4, DateBorrowed = DateTime.Parse("08/04/2014")},
new BorrowedBooks {BookId = 2, BorrowerId = 4, DateBorrowed = DateTime.Parse("08/04/2014")},
new BorrowedBooks {BookId = 1, BorrowerId = 1, DateBorrowed = DateTime.Parse("26/03/2014")},
};
private static List<Borrower> borrowers = new List<Borrower>
{
new Borrower { Id = 1, Firstname = "John", Lastname = "Smith" },
new Borrower { Id = 2, Firstname = "Mary", Lastname = "Jane" },
new Borrower { Id = 3, Firstname = "Peter", Lastname = "Parker" },
new Borrower { Id = 4, Firstname = "Eddie", Lastname = "Brock" },
};
public static List<Book> Books { get { return books; } }
public static List<BorrowedBooks> BorrowedBooks { get { return borrowedBooks; } }
public static List<Borrower> Borrowers { get { return borrowers; } }
}
public class BookRepository : IBookRepository
{
public IEnumerable<Book> Search()
{
return DataStore.Books.Where (b => b.Author == "Paul Jennings");
}
}
public class BorrowerRepository : IBorrowerRepository
{
public void Add(Borrower borrower)
{
DataStore.Borrowers.Add(borrower);
}
}

Tree structure to get parent node and its children

Please find the table structure below:
Folderid parentFolderid Guid
1 0 1234
2 1 5678
3 2 9012
4 3 87697
5 7 4443
The requirement is if I pass folderId the function has to give me all the guids.
For example:If I pass 1 to the function, I should get first four Guids(parent and its children).
I have a function which returns all the guids as follows:
public List<Guid> Folders(int folderId)
{
// To get the folderids based on parentfolderid
var a = entity.Where(x => x.parentfolderId == folderId).FirstOrDefault();
return a;
}
I am able to get only up to one level of ids.
Is there any way to get parent, its children, grandchildren till the leaf?
If you are able to get that table to a class, check this out:
public class Entity
{
public int ID { get; set; }
public int ParentID { get; set; }
public string Name { get; set; }
public static List<Entity> GetTree(int ID, List<Entity> ListToSearch, bool First = true)
{
List<Entity> FilteredEntities = new List<Entity>();
FilteredEntities.AddRange(ListToSearch.Where<Entity>(x => x.ParentID == ID).ToList<Entity>());
List<Entity> Temp = new List<Entity>();
foreach (Entity current in FilteredEntities)
{
Temp.AddRange(GetTree(current.ID, ListToSearch, false));
}
FilteredEntities.AddRange(Temp);
if (First)
{
FilteredEntities.Add(ListToSearch.Where<Entity>(x => x.ID == ID).Single<Entity>());
}
return FilteredEntities;
}
}
Usage:
List<Entity> filteredEntities = Entity.GetTree(1, entities);
List<string> onlyTheNames = filteredEntities.Select<Entity, string>(x => x.Name).ToList<string>();
Regards
If you use this node class, you can write the code like this.
public class Folder
{
public int Id { get; set; }
public int? ParentId { get; set; }
public Guid SomeGuid { get; set; }
}
and and example of what possible is:
var list = new List<Folder>
{
new Folder {Id = 0, ParentId = null, SomeGuid = new Guid("0000b25b-8538-4b78-818a-9094507e0000") },
new Folder {Id = 1, ParentId = 0, SomeGuid = new Guid("1000b25b-8538-4b78-818a-9094507e0001") },
new Folder {Id = 2, ParentId = 1, SomeGuid = new Guid("2000b25b-8538-4b78-818a-9094507e0002") },
new Folder {Id = 3, ParentId = 1, SomeGuid = new Guid("3000b25b-8538-4b78-818a-9094507e0003") },
new Folder {Id = 4, ParentId = 2, SomeGuid = new Guid("4000b25b-8538-4b78-818a-9094507e0004") },
new Folder {Id = 5, ParentId = 3, SomeGuid = new Guid("5000b25b-8538-4b78-818a-9094507e0005") },
new Folder {Id = 6, ParentId = 0, SomeGuid = new Guid("6000b25b-8538-4b78-818a-9094507e0006") },
new Folder {Id = 7, ParentId = 4, SomeGuid = new Guid("7000b25b-8538-4b78-818a-9094507e0007") },
new Folder {Id = 8, ParentId = 3, SomeGuid = new Guid("8000b25b-8538-4b78-818a-9094507e0008") },
};
var rootNode = Node<Folder>.CreateTree(list, n => n.Id, n => n.ParentId).Single();
var firstChild = rootNode.Children.First(); // Id 1
var descendentsOfFirstChild = firstChild.Descendants; // All descendants of node 1

Categories

Resources