Concatenate multiple rows into a single row in LINQ - c#

Is is possible to concatenate multiple rows to a single row?
for example:
IEnumerable<sample> sam = new List<sample>()
{
new sample{ id = 1, name = "sample 1", list = new List<int>{1,5,6}},
new sample{ id = 2, name = "sample 2", list = new List<int>{2,9}},
new sample{ id = 3, name = "sample 3", list = new List<int>{8,3,7}},
new sample{ id = 4, name = "sample 4", list = new List<int>{3,4,8}},
new sample{ id = 5, name = "sample 5", list = new List<int>{1,5,7}},
new sample{ id = 6, name = "sample 6", list = new List<int>{6,9,7}}
};
output must:
{
new sample { id = 1, name = "sample 1", list = "1,5,6" },
new sample { id = 2, name = "sample 2", list = "2,9" },
new sample { id = 3, name = "sample 3", list = "8,3,7" },
new sample { id = 4, name = "sample 4", list = "3,4,8" },
new sample { id = 5, name = "sample 5", list = "1,5,7" },
new sample { id = 6, name = "sample 6", list = "6,9,7" }
};
That means from list the new row is now a string.

Sure:
sam.Select(x => new { x.id, x.name, list = String.Join(",", x.list) });
Note: The result will be an anonymous type. We can't reuse the sample class here, because in that class list is of type List<int> and not string.
If you are stuck with .NET 3.5 or less, use this code instead:
sam.Select(x => new
{
x.id, x.name,
list = String.Join(",", x.list.Select(y => y.ToString())
.ToArray())
});
If you want to sort the list before getting the string you need to use this code:
sam.Select(x => new
{
x.id, x.name,
list = String.Join(",", x.list.OrderBy(y => y))
});

As I needed to gather several records in one column (each employee may have many specialties) and then use it in a join, this is the way I resolved:
Having these entities:
1) EMPLOYEEs Entity
|EMPLOYEE_ID|
|001 |
|002 |
2) EMPLOYEE_SPECIALTIES Entity
|EmployeeId|SPECIALTY_CODE
|001 |AAA
|001 |BBB
|002 |DDD
|002 |AAA
I needed to gather specialties by employee in one columun:
|EmployeeId|SPECIALTY_CODE
|001 |AAA, BBB
|002 |DDD, AAA
Solution:
var query = from a in context.EMPLOYEE_SPECIALTIES.ToList()
group a by a.EMPLOYEE_ID into g
select new
{
EmployeeId = g.Key,
SpecialtyCode = string.Join(",", g.Select(x =>
x.SPECIALTY_CODE))
};
var query2 = (from a in query
join b in context.EMPLOYEEs on a.EmployeeId equals b.EMPLOYEE_ID
select new EmployeeSpecialtyArea
{
EmployeeId = b.EMPLOYEE_ID,
LastName = b.LAST_NAME,
SpecialtyCode = a.SpecialtyCode
});
ViewBag.EmployeeSpecialtyArea = query2;
I hope this may help someone!

Related

Create a Lambda Expression having a WHERE IN Clause

I want to create a lambda expression dynamically for this:
List<Coverage>? excludedCoverage = originalCoverage.Where(a => currentCoverage.Select(k => k.CoverageId).Contains(a.CoverageId) == false).ToList();
I have this two lists:
var originalCoverage = new List<Coverage>() {
new Coverage { CoverageId = 1, Name = "Name 1", },
new Coverage { CoverageId = 2, Name = "Name 2", },
new Coverage { CoverageId = 3, Name = "Name 3", },
new Coverage { CoverageId = 4, Name = "Name 4", },
new Coverage { CoverageId = 5, Name = "Name 5", },
};
var currentCoverage = new List<Coverage>() {
new Coverage { CoverageId = 4, Name = "Name 4", },
new Coverage { CoverageId = 5, Name = "Name 5", },
};
I have the following codes which work for a basic WHERE clause:
var parameterExpression = Expression.Parameter(typeof(Coverage), "a");
var property = Expression.Property(parameterExpression, "CoverageId");
var expression = Expression.Equal(property, Expression.Constant(0));
var lambda = Expression.Lambda<Func<Coverage, bool>>(expression, parameterExpression);
var createLamda = lambda.Compile();
var newDatas = currentCoverage?.Where(createLamda).ToList();
How can I write an the WHERE IN clause using dynamic lambda expression?
List<Coverage>? excludedCoverage = originalCoverage.Where(a => currentCoverage.Select(k => k.CoverageId).Contains(a.CoverageId) == false).ToList();
Thanks

Case Condition with GroupBy in Linq for duplicate records

I have a list of records where I need to filter the list for duplicate records and take only one record with AddressType = "POST".
Let me show your the example:
class Test
{
public string Id {get; set;}
public string Name {get; set;}
public string AddressType {get; set;}
}
This is the data I have:
var data = new List<Test>{
new Test {Id = "1", Name = "Test11", AddressType = "POST" },
new Test {Id = "1", Name = "Test12", AddressType = "STREET" },
new Test {Id = "2", Name = "Test122", AddressType = "POST" },
new Test {Id = "3", Name = "Test123", AddressType = "POST" },
new Test {Id = "4", Name = "Test1", AddressType = "POST" },
new Test {Id = "4", Name = "Test1", AddressType = "POST" },
new Test {Id = "5", Name = "Test11", AddressType = null }
};
I'm trying to remove the duplicate records based on Id and AdressType = "POST" with this query:
var filteredData = data.GroupBy(x => x.Id).Select(x => x.First()).ToList();
This removes the duplicacy but I want to take the record with AddressType = "POST" and the above query randomly picked the First record. I have tried another thing where with this query but it is not working:
var filteredData = data.GroupBy(x => x.Id).Select(x => x.First()).Where(x => x.AddressType == "POST").ToList();
Expected Output:
Test {Id = "1", Name = "Test11", AddressType = "POST" },
Test {Id = "2", Name = "Test122", AddressType = "POST" },
Test {Id = "3", Name = "Test123", AddressType = "POST" },
Test {Id = "4", Name = "Test1", AddressType = "POST" },
Test {Id = "5", Name = "Test11", AddressType = null }
Is there anything I'm missing?
Update: Thanks to the solutions below, it worked but in case of any null value in the list. It breaks. So by adding FirstOrDefault() I'm able to handle the null error but the details of that row is not getting added to the result. Any thoughts on that?
Try putting the predicate inside the call to first:
var filteredData = data
.GroupBy(x => x.Id)
.Select(x => x.FirstOrDefault(x => x.AddressType == "POST"))
.ToList();
You can group by your selected columns then select FirstOrDefault(). try bellow;
var list = data.GroupBy(x => new { x.Id, x.AddressType })
.Select(x => x.FirstOrDefault(a => a.AddressType == "POST" || a.AddressType == null))
.Where(y => y != null)
.ToList();
Same as your expected result:
ID Name AddressType
1 Test11 POST
2 Test122 POST
3 Test123 POST
4 Test1 POST
5 Test11 null
Hope the answer helps someone.

give names to a var object in .net

just wondering I am using a web method to return some json data to a web form. anyway I don't want the entire class in json just two of the columns. so I used linq to get the columns here is an example.
IEnumerable<Person> model = new List<Person>
{
new Person { id = 1, Name = "Bryan", Phone = "218-0211", Email = "bryan#mail.mil" },
new Person { id = 2, Name = "Joe", Phone = "248-0241", Email = "joe#mail.mil" },
new Person { id = 3, Name = "Fred", Phone = "354-0441", Email = "fred#mail.mil" },
new Person { id = 4, Name = "Mary", Phone = "344-3451", Email = "mary#mail.mil" },
new Person { id = 5, Name = "Jill", Phone = "127-3451", Email = "jill#mail.mil" }
};
var mysubset = from a in model select new { a. Name, a.Email };
unfotunately when I then serialize my result and send it back I lose the column names. so data.name doesn't work so I was wondering can I give names to a var type? for example is there a way to do this?
var mysubset = from a in model select new { a. Name, a.Email };
string myname as string;
foreach (var item in mysubset)
{
myname = subset.Name;
}
ok here is the actual code sorry it is in vb but that is the project I inherited
Dim mycollection = From a in cmpnyList select {a.CmpnyName, a.ShipFrom}
return jsSerialize.Serialize(mycollection)
the json returned from that is
[{"Company A","New York"},{"Company B", "Harrisburg"}]
so I'm trying to get back something like
[{"CmpnyName":"Company A", "ShipFrom": "New York"},
{"CmpnyName": "Company B", "ShipFrom": "Harrisburg}]
I believe you're using json.net the answer would be something like this using jobject(newtonsoft.json.linq)
JObject o = new JObject(
new JProperty("PersonssList",
new JArray(
from p in model
select new JObject(
new JProperty("PersonName", p.Name),
new JProperty("Email", p.Email)))));
and the result would be this json
{
"PersonssList": [
{
"PersonName": "Bryan",
"Email": "bryan#mail.mil"
},
{
"PersonName": "Joe",
"Email": "joe#mail.mil"
},
{
"PersonName": "Fred",
"Email": "fred#mail.mil"
},
{
"PersonName": "Mary",
"Email": "mary#mail.mil"
},
{
"PersonName": "Jill",
"Email": "jill#mail.mil"
}
]

Return non-distinct object based on three different fields

Given the following, I would like to be able to pull out the non-distinct values based on two fields: Name and Country. In this example, I want return the first two in the list.
List<City> cities = new List<City>
{
new City{ Name = "Sydney", Country = "Australia", Galaxy = "Mine" },
new City{ Name = "Sydney", Country = "Australia", Galaxy = "Yours" },
new City{ Name = "New York", Country = "USA", Galaxy = "Ours"},
new City{ Name = "Paris", Country = "France", Galaxy = "Theirs" },
};
This query will return non-distinct cities by name and country (i.e. first two in your case):
IEnumerable<City> query =
cities.GroupBy(c => new { c.Name, c.Country })
.Where(g => g.Count() > 1)
.SelectMany(g => g);

How to sort an IEnumerable object by a nested IEnumerable object? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Sort a field of each object in a list with LINQ
I have this collection:
IEnumerable<sample> sam = new List<sample>()
{
new sample{ id = 1, name = "sample 1", list = new List<int>{5,6,1}},
new sample{ id = 2, name = "sample 1", list = new List<int>{2,9}},
new sample{ id = 3, name = "sample 1", list = new List<int>{8,3,7}},
new sample{ id = 4, name = "sample 1", list = new List<int>{8,4,3}},
new sample{ id = 5, name = "sample 1", list = new List<int>{5,1,7}},
new sample{ id = 6, name = "sample 1", list = new List<int>{6,9,7}}
};
How can I sort this using LINQ so that the output is:
new sample{ id = 2, name = "sample 1", list = new List<int>{2,9}},
new sample{ id = 5, name = "sample 1", list = new List<int>{5,1,7}},
new sample{ id = 1, name = "sample 1", list = new List<int>{5,6,1}},
new sample{ id = 6, name = "sample 1", list = new List<int>{6,9,7}}
new sample{ id = 3, name = "sample 1", list = new List<int>{8,3,7}},
new sample{ id = 4, name = "sample 1", list = new List<int>{8,4,3}},
This is sort by 'list' by the way.
Thanks
Here's the LINQ to order sam by the first item of the list property (I gather that's what you're after, right?):
IEnumerable<sample> orderedSam = sam.OrderBy(item => item.list.FirstOrDefault());

Categories