0

I have the following two objects:

public class BlogPost
    {
        public int BlogPostId { get; set; }
        public Author Author { get; set; }
    }

public class Author
    {
        public int AuthorId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

I have two separate lists of 50 Blog Post objects and 50 Author objects. How do I combine the two such that the Author object is assigned to the Blog Post's Author property?

I've tried using the Zip method, but I don't think that's quite what I want. This question is similar, but I want value to be an object from another list.

Context: using the Seed method in EntityFramework to populate my database.

EDIT: I should have mentioned that, because it is seed data, I don't really care which Author gets matched up to which BlogPost. Hence why I was trying to use the Zip method.

Community
  • 1
  • 1
Blake Mumford
  • 17,201
  • 12
  • 49
  • 67
  • 3
    How are the items related, only via index? Then use Zip. – Tim Schmelter Jul 08 '15 at 12:37
  • When I do this, I tend to have (using your example) AuthorId in BlogPost and have public Author Author { get { return Author.GetAuthorById(this.AuthorId); } } but ymmv – Robert Jul 08 '15 at 12:39
  • The objects are only related via Index. Sorry, should have mentioned it. – Blake Mumford Jul 08 '15 at 12:42
  • by index means, you have to have them ordered in correct order and plus one auther can have only one post. Is it practical to have a relationship by index? – Kaf Jul 08 '15 at 12:44
  • @Kaf, yes, that is correct. Sorry, the analogy of BlogPost to Author is not very good. But in this case the BlogPost can only have one Author, and I don't care which Author is assigned to which BlogPost. Sorry for the confusion. – Blake Mumford Jul 08 '15 at 12:56

2 Answers2

1

If the BlogPost and Author objects are linked via index you can use a for-loop:

for(int i = 0; i < blogPosts.Count; i++)
    blogPosts[i].Author = authors[i];

You could use LINQ approaches like Zip but then you have to create new objects from the old and fill a new list. A for-loop is much more appropriate (and efficient) if you want to modify the original collection. You can also modify only a single property without needing to copy all.

So this works also but is not the best approach (consider that BlogPost had 100 properties):

blogPosts = blogPosts.Zip(authors, (bp, a) => new BlogPost
{
    BlogPostId = bp.BlogPostId,
    Author = a
}).ToList();

But this requirement brings up the question why you didn't initialized the BlogPost-list correctly in the first place. Why do you need two separate collections at all?

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Hey, sorry your last answer before you made the edit worked perfectly! If you change it back I'll accept your answer. – Blake Mumford Jul 08 '15 at 12:48
  • @BlakeMumford: i have added it again. I have removed it because i didn't want to promote it. The for-loop is much better if you want to modify the original collection. – Tim Schmelter Jul 08 '15 at 12:53
  • Thanks, your updated answer works perfectly too! Thank you so much for your help, it's very much appreciated. Have a lovely day. – Blake Mumford Jul 08 '15 at 12:54
1

Your blogpost entity needs to maintain a FK AuthorId. When you do, you could have:

public List<BlogPost> Compose(List<BlogPost> blogPosts, List<Author> authors) {
    var composedBlogPosts = new List<BlogPost> (blogPosts);
    foreach(var blogPost in blogPosts) {
        composedBlogPost.Author = authors.Single(a=>a.AuthorId == blogPost.AuthorId);
    }
    return composedBlogPost;
}
C Bauer
  • 5,003
  • 4
  • 33
  • 62