How to order parent object by child sub object - c#

i have a List< PaperAbstract > class. a PaperAbstract class has a set of Authors. one of the Authors has a flag IsSubmitting true. how can i order my List< PaperAbstract > by the submitting authors LastName?
public class PaperAbstract
{
public string Title { get; set; }
public List<Author> Authors { get; set; }
}
public class Author
{
public bool IsSubmitting { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
for example:
var paperAbstracts = new List<PaperAbstract>();
paperAbstracts.Add(new PaperAbstract
{
Title = "Abstract 2",
Authors = new List<Author>
{
new Author { IsSubmitting = false, FirstName = "F5", LastName = "L5"},
new Author { IsSubmitting = true, FirstName = "F6", LastName = "L6"}
}
});
paperAbstracts.Add(new PaperAbstract
{
Title = "Abstract 3",
Authors = new List<Author>
{
new Author { IsSubmitting = true, FirstName = "F1", LastName = "L1"},
new Author { IsSubmitting = false, FirstName = "F2", LastName = "L2"}
}
});
paperAbstracts.Add(new PaperAbstract
{
Title = "Abstract 1",
Authors = new List<Author>
{
new Author { IsSubmitting = false, FirstName = "F3", LastName = "L3"},
new Author { IsSubmitting = true, FirstName = "F4", LastName = "L4"}
}
});
the correct order of paperAbstracts should be Abstract 3, Abstract 1, Abstract 2.

You can use OrderBy from LINQ:
var result = input.OrderBy(x => x.Authors
.First(a => a.IsSubmitting).LastName)

Related

C# ASP.NET adding a list of properties to individual users

Hi I am trying to learn how to create Web ASP.NET applications and I'm stuck on trying to get to this result.
{
"memberNumber":"1234567890",
"forename":"Fred",
"surname":"Smith",
"products":[
{
"name":"Health Ins",
"cost":100
},
{
"name":"Travel Ins",
"cost":150
}
]
}
I cannot figure out how to add different product name/cost for each individual member. I can display the memberNumber/forename/surname but get an error when I add the products.add line to the members.add line.
Here is my member model:
public class Member
{
public int memberNumber { get; set; } = 0;
public string forename { get; set; } = "";
public string surname { get; set; } = "";
public List<Products> products { get; set; }
}
public class Products
{
public string name { get; set; } = "";
public int cost { get; set; } = 0;
}
Here is my controller:
public class MembersController : ApiController
{
List<Member> members = new List<Member>();
List<Products> products = new List<Products>();
public MembersController()
{
members.Add(new Member { memberNumber = 1234567890, forename = "Fred", surname = "Smith"});
members.Add(new Member { memberNumber = 1, forename = "Big", surname = "Ben"});
members.Add(new Member { memberNumber = 2, forename = "Jack", surname = "Ryan" });
products.Add(new Products { name = "Health Ins", cost = 100 });
products.Add(new Products { name = "Travel Ins", cost = 150 });
}
// GET: api/Members
public List<Member> Get()
{
return members;
}
// GET: api/Members/5
public Member Get(int id)
{
return members.Where(x => x.memberNumber == id).FirstOrDefault();
}
}
Did not include the Post/Put/Delete RESTful services.
products.Add(new Products { name = "Health Ins", cost = 100 });
products.Add(new Products { name = "Travel Ins", cost = 150 });
will add those data in
List<Products> products = new List<Products>();
instead of your expectations in Member class.
I think you might want to add products collection in a member instead of another List
You can use Auto-Property Initializers to init products List collection in Member class.
public class Member
{
public int memberNumber { get; set; } = 0;
public string forename { get; set; } = "";
public string surname { get; set; } = "";
public List<Products> products { get; set; } = new List<Products>();
}
the MembersController constructed data will be like this.
public class MembersController : ApiController
{
List<Member> members = new List<Member>();
public MembersController()
{
var member1 = new Member { memberNumber = 1234567890, forename = "Fred", surname = "Smith"};
var member2 = new Member { memberNumber = 1, forename = "Big", surname = "Ben"};
var member3 = new Member { memberNumber = 2, forename = "Jack", surname = "Ryan" };
member1.products.Add(new Products { name = "Health Ins", cost = 100 });
member1.products.Add(new Products { name = "Travel Ins", cost = 150 });
members.Add(member1);
members.Add(member2);
members.Add(member3);
}
// GET: api/Members
public List<Member> Get()
{
return members;
}
// GET: api/Members/5
public Member Get(int id)
{
return members.Where(x => x.memberNumber == id).FirstOrDefault();
}
}
You're pretty much there, but you will need to assign a product list for each member like this:
List<Products> p= new List<Products>();
p.Add(new Products { name = "Health Ins", cost = 100 });
p.Add(new Products { name = "Travel Ins", cost = 150 });
members.Add(new Member { memberNumber = 1234567890, forename = "Fred", surname = "Smith", Products =p});
// Second member
p= new List<Products>();
p.Add(new Products { name = "Big Bens products", cost = 222});
members.Add(new Member { memberNumber = 1, forename = "Big", surname = "Ben", Products =p});
Thus you can add as many members containing as many products you wish. Please note that we're not talking about ArrayLists but about Lists. ArrayLists have been deprecated a long time ago.

Entity Framework Seed method not running

I'm having some trouble getting the Seed method of EF to run. I've run update-database in the PMC - but no effect on the DB. Here's the method:
public class PhilosopherInitialiser : System.Data.Entity.DropCreateDatabaseIfModelChanges<PhilosopherContext>
{
protected override void Seed(PhilosopherContext context)
{
var philosophers = new List<Philosopher>{
new Philosopher {
FirstName = "Bertrand",
LastName = "Russell",
DateOfBirth = DateTime.Parse("1872-05-18"),
DateOfDeath = DateTime.Parse("1970-02-02"),
IsAlive = false,
NationalityID = 1,
AreaID = 7,
Description = "Here's some text about Bertrand Russell"
},
new Philosopher {
FirstName = "Immanuel",
LastName = "Kant",
DateOfBirth = DateTime.Parse("1724-04-22"),
DateOfDeath = DateTime.Parse("1804-02-12"),
IsAlive = false,
NationalityID = 3,
AreaID = 1,
Description = "Here's some text about Immanuel Kant"
},
new Philosopher {
FirstName = "John",
LastName = "Rawls",
DateOfBirth = DateTime.Parse("1921-02-21"),
DateOfDeath = DateTime.Parse("2002-11-24"),
IsAlive = false,
NationalityID = 9,
AreaID = 3,
Description = "Here's some text about John Rawls"
}
};
philosophers.ForEach(p => context.Philosophers.Add(p));
context.SaveChanges();
var nationalities = new List<Nationality>
{
new Nationality { Name = "English" },
new Nationality { Name = "Scotish" },
new Nationality { Name = "German" },
new Nationality { Name = "French" },
new Nationality { Name = "Greek" },
new Nationality { Name = "Italian" },
new Nationality { Name = "Spanish" },
new Nationality { Name = "Russian" },
new Nationality { Name = "American" }
};
nationalities.ForEach(n => context.Nationalities.Add(n));
context.SaveChanges();
var areas = new List<Area>{
new Area { Name = "Metaphysics" },
new Area { Name = "Existentialism" },
new Area { Name = "Political philosophy" },
new Area { Name = "Philosophy of the mind" },
new Area { Name = "Aesthetics" },
new Area { Name = "Social philosophy" },
new Area { Name = "Logic" },
new Area { Name = "Moral philosophy" },
new Area { Name = "Epistemology" }
};
areas.ForEach(a => context.Areas.Add(a));
context.SaveChanges();
var books = new List<Book>
{
new Book {
Title = "The impact of science on society",
PhilosopherID = 1,
AreaID = 6
},
new Book {
Title = "The analysis of mind",
PhilosopherID = 1,
AreaID = 4
},
new Book {
Title = "Marriage and morals",
PhilosopherID = 1,
AreaID = 8
},
new Book{
Title = "Critique of pure reason",
PhilosopherID = 2,
AreaID = 9
},
new Book{
Title = "The metaphysics of morals",
PhilosopherID = 2,
AreaID = 8
},
new Book{
Title = "A theory of justice",
PhilosopherID = 3,
AreaID = 3
}
};
books.ForEach(b => context.Books.Add(b));
context.SaveChanges();
}
}
}
And here's my PhilosopherContext class:
public class PhilosopherContext : DbContext
{
public PhilosopherContext() : base("PhilosopherContext")
{
}
public DbSet<Philosopher> Philosophers { get; set; }
public DbSet<Area> Areas { get; set; }
public DbSet<Nationality> Nationalities { get; set; }
public DbSet<Book> Books { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Book>()
.HasRequired(p => p.Philosopher)
.WithMany()
.HasForeignKey(p => p.PhilosopherID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Philosopher>()
.Property(p => p.DateOfBirth)
.HasColumnType("datetime2");
modelBuilder.Entity<Philosopher>()
.Property(p => p.DateOfDeath)
.HasColumnType("datetime2");
}
}
}
Inside the Web.Config file I'm using initialising the DB here:
<contexts>
<context type="PhilosophersLibrary.DAL.PhilosopherContext, PhilosophersLibrary">
<databaseInitializer type="PhilosophersLibrary.DAL.PhilosopherInitialiser, PhilosophersLibrary" />
</context>
</contexts>
Does anyone have any suggestions? I feel that the method might not be called.
UPDATE
I seem to be making progress. The Areas and Nationalities tables are being seeded with the data. But I have to comment out the Philosophers data and the Books data. Is there something wrong with my data model?
public class Book
{
public int BookID { get; set; }
public string Title { get; set; }
[Display(Name = "Philosopher")]
public int PhilosopherID { get; set; }
[Display(Name = "Area")]
public int AreaID { get; set; }
public virtual Philosopher Philosopher { get; set; }
public virtual Area Area { get; set; }
}
public class Philosopher
{
// <className>ID pattern causes property to be primary key
public int PhilosopherID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Display(Name = "Date of birth")]
public DateTime DateOfBirth { get; set; }
[Display(Name = "Date of death")]
public DateTime DateOfDeath { get; set; }
public Boolean IsAlive { get; set; }
public string Description { get; set; }
// Foreign keys have corresponding navigation properties
// <NavigationProperty>ID naming convention cause EF to identify foreign keys
public int NationalityID { get; set; }
public int AreaID { get; set; }
// Navigation properties - defined as virtual to use LazyLoading
// Nationality and Area have a 1 to 1 relationship with philosopher
// Books has a 1 to many relationship with philosopher
public virtual Nationality Nationality { get; set; }
public virtual Area Area { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
Try to use this:
CreateDatabaseIfNotExists<PhilosopherContext>
instead of this:
DropCreateDatabaseIfModelChanges<PhilosopherContext>
Also I would add:
public PhilosopherContext() : base("PhilosopherContext")
{
Database.SetInitializer<PhilosopherContext>(new CreateDatabaseIfNotExists<PhilosopherContext>());
}

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);
}
}

How to have navigation properties without a database

I am building an app with NO persistence data. So it will be in memory.
I have the following POCO 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 created a class that will populated some sample data
public class DemoData
{
static Book book1 = new Book { Id = 1, Title = "Queen of the road", Author = "Tricia Stringer" };
static Book book2 = new Book { Id = 2, Title = "Don't look now", Author = "Paul Jennings" };
static Book book3 = new Book { Id = 3, Title = "Too bold to die", Author = "Ian McPhedran" };
static Book book4 = new Book { Id = 4, Title = "The rosie project", Author = "Graeme Simson" };
static Book book5 = new Book { Id = 5, Title = "In great spirits", Author = "Archie Barwick" };
static Book book6 = new Book { Id = 6, Title = "The vale girl", Author = "Nelika Mcdonald" };
static Book book7 = new Book { Id = 7, Title = "Watching you", Author = "Michael Robotham" };
static Book book8 = new Book { Id = 8, Title = "Stillways", Author = "Steve Bisley" };
static Borrower borrower1 = new Borrower { Id = 1, Firstname = "John", Lastname = "Smith" };
static Borrower borrower2 = new Borrower { Id = 2, Firstname = "Mary", Lastname = "Jane" };
static Borrower borrower3 = new Borrower { Id = 3, Firstname = "Peter", Lastname = "Parker" };
static Borrower borrower4 = new Borrower { Id = 4, Firstname = "Eddie", Lastname = "Brock" };
static BorrowedBooks borrowed1 = new BorrowedBooks { BookId = 8, Book = book8, BorrowerId = 2, Borrower=borrower2, DateBorrowed = DateTime.Parse("01/04/2014") };
static BorrowedBooks borrowed2 = new BorrowedBooks {BookId = 6, Book = book6, BorrowerId = 4, Borrower = borrower4, DateBorrowed = DateTime.Parse("08/04/2014")};
static BorrowedBooks borrowed3 = new BorrowedBooks { BookId = 2, Book = book2, BorrowerId = 4, Borrower = borrower4, DateBorrowed = DateTime.Parse("08/04/2014") };
static BorrowedBooks borrowed4 = new BorrowedBooks { BookId = 1, Book = book1, BorrowerId = 1, Borrower = borrower1, DateBorrowed = DateTime.Parse("26/03/2014") };
public List<BorrowedBooks> borrowedBooks = new List<BorrowedBooks>
{
borrowed1, borrowed2, borrowed3, borrowed4
};
public List<Book> books = new List<Book>
{
book1, book2, book3, book4, book5, book6, book7, book8
};
private List<Borrower> borrowers = new List<Borrower>
{
borrower1, borrower2, borrower3, borrower4
};
}
data access code
public class BookRepository : IBookRepository
{
private DemoData data = new DemoData();
public bool Add(Book book)
{
try
{
this.data.books.Add(book);
}
catch (Exception ex)
{
return false;
}
return true;
}
public bool BorrowBook(BorrowedBooks details)
{
try
{
this.data.borrowedBooks.Add(details);
}
catch (Exception ex)
{
return false;
}
return true;
}
public IEnumerable<Book> Search()
{
return data.books;
}
}
controller code
public class BookController : Controller
{
private IBookRepository _bookRepo;
public BookController(IBookRepository bookRepo)
{
_bookRepo = bookRepo;
}
public ActionResult Search()
{
var test = _bookRepo.Search();
return View(test);
}
}
But when I get the data from the repository, the navigation properties are empty... what am I doing wrong?
You need to fill collections for books in DemoData. If you don't set them yourself they are null. So in short if you don't use any persistence framework you must create relations from both sides.
For example for book1 you'll need to add:
book1.BorrowedBooks.Add(borrowed4);
And so on for all collections in all entities in your in memory database.
I think you need to make your lists static in the DemoData class as well and remove the instance private members of DemoData from you repositories. That way all your repositories will use the same data.
public static class DemoData
{
static Book book1 = new Book { Id = 1, Title = "Queen of the road", Author = "Tricia Stringer" };
static Book book2 = new Book { Id = 2, Title = "Don't look now", Author = "Paul Jennings" };
static Book book3 = new Book { Id = 3, Title = "Too bold to die", Author = "Ian McPhedran" };
static Book book4 = new Book { Id = 4, Title = "The rosie project", Author = "Graeme Simson" };
static Book book5 = new Book { Id = 5, Title = "In great spirits", Author = "Archie Barwick" };
static Book book6 = new Book { Id = 6, Title = "The vale girl", Author = "Nelika Mcdonald" };
static Book book7 = new Book { Id = 7, Title = "Watching you", Author = "Michael Robotham" };
static Book book8 = new Book { Id = 8, Title = "Stillways", Author = "Steve Bisley" };
static Borrower borrower1 = new Borrower { Id = 1, Firstname = "John", Lastname = "Smith" };
static Borrower borrower2 = new Borrower { Id = 2, Firstname = "Mary", Lastname = "Jane" };
static Borrower borrower3 = new Borrower { Id = 3, Firstname = "Peter", Lastname = "Parker" };
static Borrower borrower4 = new Borrower { Id = 4, Firstname = "Eddie", Lastname = "Brock" };
static BorrowedBooks borrowed1 = new BorrowedBooks { BookId = 8, Book = book8, BorrowerId = 2, Borrower=borrower2, DateBorrowed = DateTime.Parse("01/04/2014") };
static BorrowedBooks borrowed2 = new BorrowedBooks {BookId = 6, Book = book6, BorrowerId = 4, Borrower = borrower4, DateBorrowed = DateTime.Parse("08/04/2014")};
static BorrowedBooks borrowed3 = new BorrowedBooks { BookId = 2, Book = book2, BorrowerId = 4, Borrower = borrower4, DateBorrowed = DateTime.Parse("08/04/2014") };
static BorrowedBooks borrowed4 = new BorrowedBooks { BookId = 1, Book = book1, BorrowerId = 1, Borrower = borrower1, DateBorrowed = DateTime.Parse("26/03/2014") };
public static List<BorrowedBooks> borrowedBooks = new List<BorrowedBooks>
{
borrowed1, borrowed2, borrowed3, borrowed4
};
public static List<Book> books = new List<Book>
{
book1, book2, book3, book4, book5, book6, book7, book8
};
private static List<Borrower> borrowers = new List<Borrower>
{
borrower1, borrower2, borrower3, borrower4
};
}
Then in your book repository, you access via the static members rather than an instance field.
public class BookRepository : IBookRepository
{
public bool Add(Book book)
{
try
{
DemoData.books.Add(book);
}
catch (Exception ex)
{
return false;
}
return true;
}
public bool BorrowBook(BorrowedBooks details)
{
try
{
DemoData.borrowedBooks.Add(details);
}
catch (Exception ex)
{
return false;
}
return true;

Flatten LINQ Collection

I have had a look at this Flatten LINQ collection object with nested object collections but it doesn't quite do it for me.
I know there is a lot of code in this post but it's mostly just data to give you the idea of what I'm looking at developing.
if you look at the classes below, I am trying to come up with a way to flatten the result of a search against the file.
So i need to end up with a single flattened record which looks like (the pipes are there to show delimination of a field only)
fileId | FileContact1FirstName | FileContact1LastName | FileContact2FirstName etc | FileClient1FirstName | FileClient1LastName | FileClient1IsNominee | FileClient1IsPrimary | FileClient2FirstName etc....
Any idea on how I can do this without looping through each Contact and Client?
I have these classes of sorts in my edmx;
class File
{
public int fileId { get; set; }
public List<FileContact> fileContacts { get; set; }
public List<FileClient> fileClients { get; set; }
}
class FileContact
{
public Contact contact { get; set; }
}
class FileClient
{
public Contact contact { get; set; }
public bool IsNominee { get; set; }
public bool IsPrimary { get; set; }
}
class Contact
{
public int id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
}
And this this as the data simply for testing.
static void FillData()
{
thisFile = new File { fileId = 1, fileContacts = new List<FileContact>(), fileClients = new List<FileClient>() };
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Andrew", lastName = "Albino" } });
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Bob", lastName = "Bush" } });
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Cathy", lastName = "Conti" } });
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Drew", lastName = "Dram" } });
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Edward", lastName = "Eliston" } });
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Frank", lastName = "Fashion" } });
thisFile.fileContacts.Add(new FileContact { contact = new Contact { id = 1, firstName = "Graham", lastName = "Grape" } });
thisFile.fileClients.Add(new FileClient { contact = new Contact { id = 1, firstName = "Harry", lastName = "Who didn't" }, IsNominee = true, IsPrimary = false });
thisFile.fileClients.Add(new FileClient { contact = new Contact { id = 1, firstName = "Indigo", lastName = "Ignacio" }, IsNominee = false, IsPrimary = false });
thisFile.fileClients.Add(new FileClient { contact = new Contact { id = 1, firstName = "Julie", lastName = "Juniper" }, IsNominee = false, IsPrimary = false });
thisFile.fileClients.Add(new FileClient { contact = new Contact { id = 1, firstName = "Kelly", lastName = "Keilor" }, IsNominee = false, IsPrimary = false });
thisFile.fileClients.Add(new FileClient { contact = new Contact { id = 1, firstName = "Liam", lastName = "Loser" }, IsNominee = false, IsPrimary = true });
}
}
This will get you an IEnumerable<string> that contains the properties in the order you specified:
var flattened = new string[] { thisFile.fileId.ToString() }
.Concat(
thisFile.fileContacts
.SelectMany(fc => new string[]
{
fc.contact.firstName,
fc.contact.lastName
}))
.Concat(
thisFile.fileClients
.SelectMany(fc => new string[]
{
fc.contact.firstName,
fc.contact.lastName,
fc.IsNominee.ToString(),
fc.IsPrimary.ToString()
}));
Example: http://ideone.com/Mvc7M
Have a look at SelectMany.

Categories

Resources