Add element to a List when delcaring new object - c#

Is there a way to add elements to a List when doing this:
var Foo = new MyClass() {
PropertyList = MyList,
Id = Id,
}
I would like to add elements to PropertyList. For example would be the same as: MyList.Add()
The problem is that i do not have a list called MyList but i rather have elements that i want to append to PropertyList
Updating code based on comments:
var result1 = await query
.GroupBy(c => new {
c.CommissionId, c.ActivityId
})
.Select(grp => new RegistrationStatisticViewModel() {
CommissionId = grp.Key.CommissionId,
CommissionCode = grp.First().Commission.Code,
CommissionDescription = grp.First().Commission.Description,
MinuteWorked = grp.Sum(c => c.MinuteWorked),
ActivityId = grp.Key.ActivityId,
ActivityCode = grp.First().Activity.Code,
ActivityDescription = grp.First().Activity.Description,
})
.ToListAsync();
var grps = from d in result1
group d by d.CommissionId
into grp
select new RegistrationStatisticViewModel() {
CommissionId = grp.Key,
ActivityList = new List < Activity > {
new Activity {
//ActivityId = grp.Select(d => d.ActivityId),
//Code = grp.Select(d => d.ActivityCode),
//Description = grp.Select(d => d.ActivityDescription),
}
},
CommissionCode = grp.First().CommissionCode,
CommissionDescription = grp.First().CommissionDescription,
MinuteWorked = grp.First().MinuteWorked
};
return grps;
To give context:
forget the result1 is just some data i retrieve from my database
Commission is one class and contains:
CommissionId
Code
Description
Activity is one class and contains:
ActivityId ==> type GUID
Code ==> type string
Description ==> type string
Now the var = grps is a LINQ that gets the data and then instatiates a new object (class) new RegistrationStatisticViewModel()
So the tricky part we were discussing before is when i populate ActivityList with multiple activities.
When populating the list if i use .First() or .Select() i would only get one instance and therfore the list would only have one activity.
It worked when using .ToArray() for example if i replace ActivityList with just the ActivityId of type string (so a new property on RegistrationStatisticViewModel that is not a list anymore):
I can do this ActivityId = grp.Select(d2 => d2.ActivityId).ToArray()
And it will give me an array of all the ActivityId linked to that commissionId
I am sorry if this is confusing but it is for me as well. I would thank you if you could help me. No worries if you can't you have already give me very helpful answers, so i thank you for that!

Based on your remarks, I believe this is what you are trying to achieve:
public class PersonContainer
{
public IList<Person> Persons { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
var personContainer = new PersonContainer
{
Persons = new List<Person>
{
new Person
{
Name = "John Doe",
Age = 28,
},
new Person
{
Name = "Jane Doe",
Age = 27,
},
}
};
Here, the Persons property of PersonContainer is initialized and populated with Person elements during instantiation.

Related

Problem using "Any" method inside "Where" method in Linq MongodbDriver

I'm new in using linq and having some problem . I've got a big collection of type A and a small collection of type B.
I want the list of items in A which their "id" does exist in B.
So here is what I did think could work:
List<string> list = collection_A
.Where(c => collection_B.Any(x => x.MessageId == c.Id))
.Select(c=>c.Id)
.ToList();
I'm using mongoDB linq provider in .Net and the error is : System.ArgumentException: Unsupported filter. The relation is 1-1
Actually I don't know if I should use "Join" in this case or something else.
I'd suggest that you try this:
var messageIds = new HashSet<string>(collection_B.Select(x => x.MessageId).Distinct());
List<string> list =
collection_A
.Where(c => messageIds.Contains(c.Id))
.Select(c => c.Id)
.ToList();
if i understood your problem correctly, the following code will point you in the right direction.
i've used MongoDAL for data access which is just an abstraction around the c# driver.
using System;
using System.Linq;
using MongoDAL;
namespace Example
{
class Person : Entity
{
public string Name { get; set; }
}
class BanRecord : Entity
{
public One<Person> Person { get; set; }
public string ReasonForBan { get; set; }
}
class Program
{
static void Main(string[] args)
{
new DB("testdatabase");
var person1 = new Person { Name = "Person One" };
var person2 = new Person { Name = "Person Two" };
var person3 = new Person { Name = "Person Three" };
person1.Save();
person2.Save();
person3.Save();
var ban1 = new BanRecord
{
Person = person1.ToReference(),
ReasonForBan = "Cause we can!"
};
ban1.Save();
var ban2 = new BanRecord
{
Person = person2.ToReference(),
ReasonForBan = "Cause we can!"
};
ban2.Save();
var bannedPeople = (from b in DB.Collection<BanRecord>()
join p in DB.Collection<Person>() on b.Person.ID equals p.ID into banned
from p in banned
select p).ToArray();
Console.ReadKey();
}
}
}

Flatten collection of key-collection items Linq

How would I go about flattening below structure using Linq?
I'm looking at following result:
Date Ids
1/1/2011 1
1/1/2011 2
1/1/2011 3
1/1/2012 3
etc..
I tried SelectMany, but I'm doing it wrong. Some snippets for this example:
public class DTO
{
public DateTime Date { get; set; }
public List<int> Ids { get; set; }
}
as
var dataSet = new List<DTO>{
new DTO {Date = new DateTime(2011,1,1), Ids = new List<int>{1,2,3} },
new DTO {Date = new DateTime(2012,1,1), Ids = new List<int>{3,4,5} },
new DTO {Date = new DateTime(2013,1,1), Ids = new List<int>{5,6,7} }
};
You're looking to SelectMany
var result = dataSet.SelectMany(x => x.Ids, (dto,id) => {
return new { date = dto.Date,id};
});
Live example: http://rextester.com/GHY67873
The selectmany should be on the lists inside the DTO but while keeping a reference to the date. That's probably the main issue. By using query syntax those constructions are a lot easier:
var res = (from s in dataSet
from id in s.Ids
select new {Date=s.Date, Id = id}).ToList();
And yet another SelectMany variant with an inner Select
var result = dataSet.SelectMany(x => x.Ids.Select(id => new { date = x.Date,id}));
If you still want Ids as list you can do
var newDataSet = from dto in dataSet
from id in dto.Ids
select new DTO { Date = dto.Date, Ids = new List<int> { id }};
If you want a single id property like
public class NewDTO
{
public DateTime Date { get; set; }
public int Id { get; set; }
}
You can do
var newDataSet = from dto in dataSet
from id in dto.Ids
select new NewDTO { Date = dto.Date, Id = id };
Here another solution using SelectMany
var results = dataSet.Select(x => new
{
dto = x.Ids.Select(y => new
{
date = x.Date,
id = y
})
}).SelectMany(x => x.dto).ToList();

Sum List<T> Properties of each item in List<T>

Please refer to ff. codes:
MainObj:
public class MainObj {
public string Name { get; set; }
public int SomeProperty { get; set; }
public List<SubObj> Subojects { get; set; }
}
SubObj:
public class SubObj {
public string Description { get; set; }
public decimal Value { get; set; }
}
QUESTION: I have a List<MainObj>. Each item has equal number of SubObj. How do I sum the values of each SubObj from MainObj A which corresponds to the same index as the SubObj in the other MainObj in the list.
To illustrate further:
Results:
{
Name: "something....",
Value: SUM(MainObj_A.SubObj[0], MainObj_B.SubObj[0] .... MainObj_n.SubObj[0]
},
{
Name: "don't really care...."
Value: SUM(MainObj_A.SubObj[1], MainObj_B.SubObj[1] .... MainObj_n.SubObj[1]
},
{
Name: "don't really care...."
Value: SUM(MainObj_A.SubObj[2], MainObj_B.SubObj[2] .... MainObj_n.SubObj[2]
}
.... so on and so forth
I know I can loop thru each item in MainObj then perform the sum but I was hoping that there is a simpler way using Linq.
Sorry if I can't put the right words for my question. I hope the illustrations helped.
Every help would be much appreciated. CHEERS!
As I understand the question you look for something like this:
var results = list.Select((m, i) => new
{
m.Name,
Value = list.Sum(t => t.SubObj[i].Value)
}).ToList();
This creates a list of an anonymous type containing the name of each main object and the sum of all subobject values with the same index as the main object.
It's not clear from your question, but if you want to sum all subojects (not only as many as there are main objects), you can do it like this:
var results = Enumerable.Range(0, list[0].SubObj.Count)
.Select(i => list.Sum(m => m.SubObj[i].Value)).ToList();
This gives you a list of the sums (without names, as your examples suggest that you "don't really care" about any names).
For flexibility and slightly boosted performance, I'd prefer a mixed LINQ-sql way as shown in my answer below.
var result = from x in list
where x...
group x by x.SomeProperty
into item
select new {
Id = item.Key,
Name = item.Name,
Value = item.SubObj.Sum(i => i.Value)
};
I would extend solution of Rene, to sum over all subitems:
var result = list.First().Subojects.Select((m, i) => new
{
Name = i.ToString(),
Value = list.Sum(t => t.Subojects[i].Value)
}).ToList();
i have used it with this values:
var list = new List<MainObj>
{
new MainObj { Name = "A", Subojects = new List<SubObj>{new SubObj{ Value = 1}, new SubObj{ Value = 2}, new SubObj{ Value = 3}}},
new MainObj { Name = "B", Subojects = new List<SubObj>{new SubObj{ Value = 1}, new SubObj{ Value = 2}, new SubObj{ Value = 3}}}
};
And result is:
0:2
1:4
2:6

Getting List of Model1 with List of Model2 in it LINQ - MVC 4 EntityFramework 5

I have a requirement where I need to get a List of Model1 (List) using Linq, the Model1 have List of Model2 (List) in it and I need to fetch that also. For this I have created a Linq but m getting following error:
LINQ to Entities does not recognize the method
'System.Collections.Generic.List1 [OurCourse]
ToList[OurCourse](System.Collections.Generic.IEnumerable1
[OurCourse])' method, and this method cannot be translated into a
store expression.
Please refer below for detail:
I have two tables Colleges and Courses, with following columns:
College: ID, Name, Contact, City, Address
Cource: ID, CollegeID, Name, Years
My project have two view models for them, as follows:
public class OurCollege
{
public string Name { get; set; }
public string Contact { get; set; }
public List<OurCourse> MyCourses { get; set; }
}
public class OurCourse
{
public string Name { get; set; }
public int NumberOfYears { get; set; }
}
Here the the query query which I have prepared but I am getting the error:
var colleges = db.Colleges
.Select(cld => new OurCollege()
{
Name = cld.Name,
Contact = cld.Contact,
MyCourses = cld.Course
.Select(crs => new OurCourse()
{
Name = crs.Name,
NumberOfYears = crs.Years
}).ToList()
}).ToList();
How about doing like this:
MyCourses = from crs in cld.Course
select new OurCourse
{
Name = crs.Name,
NumberOfYears = crs.Years
}
Your complete query will look now:
var colleges = db.Colleges
.Select(cld => new OurCollege()
{
Name = cld.Name,
Contact = cld.Contact,
MyCourses = (from crs in cld.Course
select new OurCourse
{
Name = crs.Name,
NumberOfYears = crs.Years
}).ToList()
}).ToList();
Actually LINQ to Entities converts your query into SQL.It doesn't know how to translate ToList() in SQL
An alternate is to change you List<T> to IEnumerable<T> and remove ToList() frim your original code:
public IEnumerable<OurCourse> MyCourses { get; set; }
and in query:
var colleges = db.Colleges
.Select(cld => new OurCollege()
{
Name = cld.Name,
Contact = cld.Contact,
MyCourses = cld.Course
.Select(crs => new OurCourse()
{
Name = crs.Name,
NumberOfYears = crs.Years
})
}).ToList();
For more details visit this Entity Framework ToList() in nested type (LINQ to Entities does not recognize the method)
A foreach loop will work, you can write the query something like this
var colleges = db.Colleges
.Select(x => new OurCollege()
{
CollegeId = x.CollegeId,
Name = x.Name,
Contact = x.Contact
}).ToList();
foreach (var college in colleges)
{
college.MyCourse = db.Course.Where(x => x.CollegeId == college.CollegeId)
.Select(x => new OurCourse()
{
Name = x.Name,
NumberOfYears = x.Years
}).ToList()
}

How to get the second element alone from a list which contains 2 elements in c#.net?

This is my list definition
public class EventsList
{
public int EventID { get; set; }
public string EventName { get; set; }
}
This is C# code
string strCurrentUser = CommonWeb.GetLoginUser();
EventsClass EventObj = new EventsClass();
DataSet ds;
List< EventsList> eventList = new List<EventsList>();
EventsList eventobj = new EventsList();
ds=EventObj.GetEvents(strCurrentUser);
I have a drop down in which it shoould display the EventName alone. How could i achieve this??
Your question isn't clear, but it sounds like it might be as simple as using the indexer of List<T>, which makes accessing an element look like array access:
List<string> values = ...;
string name = values[1]; // Index is 0-based
For a more general IEnumerable<string> you can use the ElementAt extension method:
using System.Linq;
...
IEnumerable<string> values = ...;
string name = values.ElementAt(1);
.Select(i => i.Name);
e.g.
static void Main(string[] args)
{
var records = GetPersonRecords();
var onlyName = records.Select(i => i.Name);
}
private static List<Person> GetPersonRecords()
{
var listPerson = new List<Person>();
listPerson.Add(new Person { Id = 1, Name = "Name1" });
listPerson.Add(new Person { Id = 2, Name = "Name2" });
return listPerson;
}
}
class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
Hope this helps
Power of Linq we can achieve this...
Below example I Retrieve the particular Property alone..
List<Item> oListItem = new List<Item>() {
new Item("CD", "001CD", Enum.GroupTYPE.FAST_MOVING),
new Item("TV", "002CD", Enum.GroupTYPE.FAST_MOVING),
new Item("CD", "001CD", Enum.GroupTYPE.FAST_MOVING),
new Item("LAPTOP", "003CD", Enum.GroupTYPE.FAST_MOVING),
new Item("MOBILE", "004CD", Enum.GroupTYPE.NORMAL),
new Item("CHARGER", "005CD", Enum.GroupTYPE.LEAST_MOVING)
};
Retrieve the Name property alone from the Collection
var Item = from Item oname in oListItem select oname.ItemName;
it can be easily achieved using LINQ. Also, we can modify how we want to distinguish the required item.
var Item = oListItem.Select(x=>new Item()).Skip(1).Take(1);
Skip = How many items we want to skip
Take = How many we want to take

Categories