I'm new to the 4.0 framework (coming from 2.0), and I'm not entirely sure how to phrase this question so I figured it would be easiest to ask opposed to trying my luck with google.
Here's the scenario:
Let's say I have a collection of class "Wheel", and I have a second collection of class "Vehicle", where each vehicle object has a collection of "Wheel". My objective is to add every Vehicle's Wheels to my Wheel collection.
With the extension methods, is there another way to do this:
foreach(Vehicle v in vehicles)
{
wheels.AddRange(v.Wheels);
}
Or more specifically, in my actual use case there would only be one wheel (I need to add a specific member of each object in a collection to another collection):
foreach(Vehicle v in vehicles)
{
wheels.Add(v.Wheel);
}
I realize doing the above is pretty simple in itself, but for this project I'd like to use the additions to 3.5/4.0 wherever possible.
Thanks!
A little bit of LINQ will do the trick
wheels.AddRange(vehicles.SelectMany(v => v.Wheels));
Thanks Fourth, I should point out the other case. If there is just one wheel then Select will work:
wheels.AddRange(vehicles.Select(v => v.Wheel));
There is another approach:
vehicles.ForEach(v => { wheels.AddRange(v.Wheels); });
Or in case of one wheel:
vehicles.ForEach(v => { wheels.Add(v.Wheel); });
Related
I have a list of objects and each object has a property that is a list of another object. Within this logic I'm casting the first object from a base class to one of it's inheriting classes.
It's this final list I want to make my changes to.
I've tried a few things already and I can see stepping through that the logic is executing but the finished product is always unchanged.
I've tried using linq:
Object1BaseObjectList
.Cast<Object1InheritedClass>()
.ToList()
.ForEach(e =>
e.Object2List
.ToList()
.ForEach(p => p.boolValue = true));
And I've tried some more conventional code:
foreach (Object1InheritedClass object1 in Object1BaseObjectList)
{
foreach (Object2Class object2 in object1.Object2List)
{
object2.boolValue = true;
}
}
Like I said the end result for both of these is no change. Anyone have any ideas as to what is going wrong here?
Just answering for the sake of closing this out. The information I provided was not enough to answer the question. Turns out the issue was being caused by the second list being declared as an IEnumerable. Changing it to a list corrected it. I'm assuming this was because IEnumerable wasn't creating a deep copy.
I'm sending messages to individual users depending on their roles, to accomplish that I have the following piece of code:
public static void Add(Guid userId, IEnumerable<SnapshotItem> snapshot)
{
var hub = GlobalHost.ConnectionManager.GetHubContext<FeedbackHub>();
var items = ApplicationDbContext.Instance.InsertSnapshot(userId, Guid.NewGuid(), snapshot);
foreach (var sendOperation in ConnectedUsers.Instance.EnumerateSendOperations(items))
{
hub.Clients.Users(sendOperation.Groups.SelectMany(x => x.Users).Select(x => x.Id).ToList()).OnDataFeedback(sendOperation.Items);
}
}
I'm not sure why do I have to invoke .ToList() each time I need to send something, my backing store is HashSet<String> and I want SignalR to work with that type of store instead of converting it to List each time since it would obviously consume processing power and memory.
Since in the backstage SignalR is doing simple iteration over the argument users or connectionIds, wouldn't it be more wise to use IEnumerable instead of IList, I've looked into the SignalR sources, shouldn't be to hard to achieve? Is there a particular reason for using the IList?
Edit
Created an issue on SignalR github page, will have to wait for one of the actual devs in order to clear things out...
There's no good reason for this as far as I can see digging through the older source code. The irony of it is that the IList<string> gets handed into the MultipleSignalProxy class where it is promptly mapped to a different format using another LINQ expression and then that is .ToList()'d. So, based on that exact usage in the implementation, they really don't need anything more than IEnumerable<string>.
My best answer would be that SignalR internally uses the enhanced function of IList like getting the count, or iterating over the collection and the additional use of index based access you would use for IList, but not ICollection. The only reason to use the more robust class is because somewhere they are using it, or feel the need for that additional functionality. Otherwise I would assume best practices of using the lighter class of ICollection, or IEnumerable, basically the base class of that Enumerable->Collection->List heirarchy.
G
What does the theory say about this? Which of the two is the right approach?
Let's take two entities - a Question entity and a Tag one, just like here in StackOverflow. Assume that the code below is part from a controller's method supposed to create a Question entity. Remember that a Question may have Tags. So, this method should create both - a Question and its Tags (if there are any).
Qustion questionDbContext = new Qustion();
// Mapping the model properties to the entity's ones.
questionDbContext.Title = questionModel.Title;
questionDbContext.Body = questionModel.Body
// More mapping..
// ...
// Here Entity Framework will add all the necessary Tag and QuestionTag entities automatically.
questionDbContext.Tags = questionModel.Tags.Select(t => new Tag(t)).ToList();
this.questionsRepository.Add(questionDbContext);
this.questionsRepository.Save();
The other approach I can think of is quite different.
Qustion questionDbContext = new Qustion();
// Mapping the model properties to the entity's ones.
questionDbContext.Title = questionModel.Title;
questionDbContext.Body = questionModel.Body
// More mapping..
// ...
// Tag mapping
foreach(var tag in questionModel.Tags)
{
Tag tagDbContext = new Tag();
tagDbContext.Name = tag.Name
// More mapping..
this.tagsRepository.Add(tagDbContext);
}
this.questionsRepository.Add(questionDbContext);
this.questionsRepository.Save();
this.tagsRepository.Save();
So, which approach is right? If neither of them, share yours, thank you :)
First I think this is better placed in code review, rather than SO. But to answer your question, In my anecdotal experience, the difference is really small. I would say go for whichever is easiest for you to use, and read. On that note I would personally go for the first.
Side Note: if you do want to go the foreach() route, and speed is a primary factor, I would instead use a normal for loop
for(int i=0;i<QuestionModel.Tags;i++){...}
As the simple for loop is faster than a foreach loop. Ether way I would still air towards readability than small performance gains.
It appears that AutoMapper's methods BeforeMap and AfterMap have a critical bug, which if one is attempting to iterate over a collection of the source object to populate a property of the destination object, those mapping methods execute more than once. See: Extra iterations in a foreach in an AutoMapper map
What I'm trying to do is a bit complicated, so please bear with me.
I have a EF4 many-to-many graph (Games-to-Platforms) I'm trying to build based on incoming form data. In order to build the graph, I take the raw integer ids that come from the form, and then grab the correct Platforms from my repository in order to add them to the Game's collection. You can see my attempt at doing this within BeforeMap in the link I provided above.
The problem is that I'm not sure how to proceed. I need to be able to grab a hold of the destination (Game) object in order to successfully Add the Platforms to the Game. Is something like this possible in ForMember? From what I've read, it doesn't look like a custom resolver would work for me, and I'm not sure how I'd implement a custom type converter given all the moving parts (two entities, repository).
Any ideas or suggestions?
I simply decided to make my own static mapper. Not an ideal, or even great solution, but it works. It can definitely be made more abstract, but I figure it's a band-aid until AutoMapper is fixed. My solution:
public static class GameMapper
{
public static Game Map(IGameRepository repo, AdminGameEditModel formData, Game newGame)
{
newGame.GameID = formData.GameID;
newGame.GameTitle = formData.GameTitle;
newGame.GenreID = formData.GenreID;
newGame.LastModified = DateTime.Now;
newGame.ReviewScore = (short)formData.ReviewScore;
newGame.ReviewText = formData.ReviewText;
newGame.Cons = String.Join("|", formData.Cons);
newGame.Pros = String.Join("|", formData.Pros);
newGame.Slug = formData.Slug;
if (newGame.Platforms != null && newGame.Platforms.Count > 0)
{
var oldPlats = newGame.Platforms.ToArray();
foreach (var oldPlat in oldPlats)
{
newGame.Platforms.Remove(oldPlat);
}
}
foreach (var platId in formData.PlatformIDs)
{
var plat = repo.GetPlatform(platId);
newGame.Platforms.Add(plat);
}
return newGame;
}
}
Unfortunately, I can't make the third parameter an out parameter due to my need to overwrite existing entity data during updating. Again, it's definitely not a pretty, or even good solution, but it does the job. I'm sure the OO gods will smite me at a later date.
I have this code which, on the front-end, will create dependent selectboxes (subcategories are dependent on the category) using LINQ:
foreach (var cat in (from category in KB.Categories
orderby category.name
select category)) {
this.categories.Add(cat.id, cat.name);
}
foreach (var sub_cat in (from subcategory in KB.SubCategories
orderby subcategory.name
select subcategory)) {
this.subcategories.Add(sub_cat.id, sub_cat.name);
if (!this.subcategoryCategory.containsKey) {
this.subcategoryCategory.Add(sub_cat.category_id, new ArrayList());
}
// I'd like to put the sub_cat_id at the end of the arraylist
// for the category_id, but this line doesn't seem to work
//this.subcategoryCategory[sub_cat.category_id] = sub_cat.id;
}
How can I do this?
Perhaps there a way to build a giant JSON object instead of the three variables (categories, subCategoryCategory, subcategories)?
Is there a better/different way to do this that I've completely missed?
P.S. Coming from a different programming paradigm, I'm not doing this in the standard ASP.NET (webforms or MVC) way, but I am using codebehind to generate the values.
It looks like you actually want a Lookup, e.g.
var subcategories = KB.SubCategories.ToLookup(subcat => subcat.id,
subcat => subcat.name);
However, it's not really clear given that you've got subcategories, subcategoryCategory and categoies, all of which are instance variables which you haven't shown us the type for... and your if clause doesn't specify which key it's trying to use. It's all a bit confused at the moment...
My guess is that you should look at ToLookup and also ToDictionary, which are made for this sort of thing.
JSON.NET might solve this problem, with its ability to convert JSON objects to C# and back. See this SO question for an example.