Create a list of one object type from a list of another using Linq - linq

If I have classes of Type A and B:
public class A
{
public int TotalCount;
public string Title;
}
public class B
{
public int Count;
public string Title;
}
I have a list of instances A instances, what is the most efficient way to create and populate a List of type B using Linq?

List<B> listB = listA.Select(a => new B()
{
Count = a.TotalCount,
Title = a.Title
}).ToList();
Does the same as eduncan's solution with different syntax. Take your pick..

var list =
from a in TableA
select new B {
Count = a.TotalCount,
Title = a.Title
};
You new up an instance of B in your select clause, and assign the properties using the inline property assignment feature in C# 3.0.
The advantages of mapping it inline comes from deferred execution of your Linq statement. Linq will map the modified statement, and execute it from your IQueryable. For example:
public class ClassA
{
public int TotalCount;
public string Title;
}
public class ClassB
{
public int Count;
public string Title;
}
public IQueryable<ClassB> FetchAllOfClassB()
{
var list =
from a in TableOfClassA
select new ClassB {
Count = a.TotalCount,
Title = a.Title
};
return list.AsQueryable();
}
Technically, the AsQueryable() is a bit redundant. Sometimes I use it to make it a point, others say it is absolutely required. None the less, the list object itself is IQueryable of ClassB.
Then you can call FetchAllOfClassB() further up the chain, and use IQuerable. It's pretty slick, and efficient.

Hmm, off the top of my head (so there will probably be errors!):
List< B > = from a in listOfA select new B(a.count, a.title);
might do the trick.

Related

Automapper to Map two List Classes of different structure and also Memberwise explicit Mapping

I have 4 classes namely ClassA, ClassADto, ClassAA(inner class to ClassA) and the final Result class.
ClassAA
{
public int HouseNumber{get;set;}
public string StreetName{get;set;}
public string State{get;set;}
}
ClassA
{
public int Age{get;set;}
public string Name{get;set;}
public ClassAA AObj[get;set;}
}
ClassADto
{
public int Age{get;set;}
public string Name{get;set;}
}
class Result
{
public string StreetName{get;set;}
public int TotalCount{get;set;}
public int TodaysDate{get;set;}
public List<ClassADto> AObjectsList{get;set;}
}
Now my aim is map the 'Result' class with the List of ClassA object to fill it the property 'AObjectsList' as below:
Result data= map mapper.map>(obj);
Also at the same time in automapper i want to use custom function either using 'Resolve' or 'AfterMap' to set properties like 'TodaysDate' to current datetime of system and property 'TotalCount' by counting the number of data.
I tried in many ways using 'CreateMap' and also used 'ForMembers' as from 'classAA' we only need the 'StreetName' but it didn't work. Need some help please.
One time typing approach ;)
public static Result ToResult(this List<ClassA> users)
{
return new Result
{
TotalCount = users.Count,
TodaysDate = DateTime.Today,
AObjectsList = users
.Select(user => new ClassADto
{
Name = user.Name,
Age = user.Age
})
.ToList()
};
}
// Usage
var users = new List<ClassA> { new ClassA(), new ClassA() };
var result = users.ToResult();

Android: update single Room column with Dao call from repository?

I have a Room database and RecyclerView that shows a list of CardViews. One of the database columns holds Sort Index values so the CardViews can easily be sorted and moved within the RecyclerView list. I have a Dao call to update the Sort Index values whenever a CardView is moved, deleted or added.
Room requires CRUD on a background thread and the syntax I have in the AsyncTask() in the respository that calls the Dao method is wrong. I am trying to pass the individual "int" sortOrders and the "int" sortIds. What am I missing here? Or would " Executor mExecutor = Executors.newSingleThreadExecutor();" be a better solution here?
MainActivity
int sortId = -1;
int sortOrder = -1;
...
mViewModel.updateSortOrder(sortOrder, sortId);
ViewModel
...
public void updateSortOrder(int sortOrder, int sortId) {
repository.updateSortOrder(sortOrder, sortId);
}
Repository
...
public void updateSortOrder(int sortOrder, int sortId) {
new UpdateSortOrderColAsyncTask(quickcardDao).execute(sortOrder, sortId);
}
**I think this is where the syntax is not correct**
private static class UpdateSortOrderColAsyncTask extends AsyncTask<Integer, Void, Void> {
private QuickcardDao asyncTaskDao;
UpdateSortOrderColAsyncTask(QuickcardDao dao) {
asyncTaskDao = dao;
}
#Override
protected Void doInBackground(final Integer... params) {
asyncTaskDao.updateSortorder(params[0]);
return null;
}
}
Dao
#Query("UPDATE cards SET cardSortorder = :sortOrder WHERE cardId = :sortId")
void updateSortorder(int sortOrder, int sortId);

ICollection properties Sorting in ASP.Core using LINQ

How to sort Icollection properties.For example:
public class INSTRUCTOR
{
public int Id
public string Name
public PersonalDetails PersonalDetail
}
public class PersonalDetails
{
public int Id;
public string Firstname;
public ICollection<Emails> Emails;
}
public class Emails
{
public int Id;
public string Email;
}
Now I have the list pages of instructor and I got all instructors like this:
var instructors = db.instructors.include(p=>p.personaldetails).Tolist();
I can sort using instructorName using the following Code:
instructors = instructors.OrderBy(i => i.PersonalDetail.Firstname).ToList();
But, I want to know how to do with using emails which is ICollection?
In some way you're going to have to flatten the Email collection in order to sort the parent collection by it, either by applying some aggregate function or by for example joining it into a string.
If you for example make the assumption that the first Email address in the list is the primary address, then it could make sense to sort only by this item;
var orderedList =
instructors.OrderBy(i => i.PersonalDetails.Emails.FirstOrDefault()?.EmailAddress).ToList();
You could also choose to order by the "smallest" email address in the list by applying the Min() aggregate function;
var orderedList =
instructors.OrderBy(x => x.PersonalDetails.Emails.Min(e => e.EmailAddress)).ToList();

Using Linq to select from a List in a List with Contains

I'm having syntax troubles.
public class Student
{
int StudentId;
string Name;
}
public class Course
{
int CourseId;
List<Student> Students;
}
int[] studentIds = { 5, 7, 12 };
List<Course> allCourses = myDataContext.Courses.ToList();
Using Lambda expressions or query expressions, how do I get a filtered list of all the Courses containing any of the Students in the array studentIds?
var result = from course in allCourses
where course.Students.Any(x => studentIds.Contains(x.StudentId))
select course;

Returning a custom list class type from LINQ Query - return same type going in that is coming out

I have a custom List (MyCustomList) that implements List(Of MyCustomClass).
I want to run a LINQ query against that and return a filtered MyCustomList.
Public ReadOnly Property DebitTransactions As MyCustomList
Get
Return From item In Me Where item.IsDebit = True Select item
End Get
End Property
I get a type conversion here because the LinQ query doesn't return the list in the same MyCustomList that it was filtering. It cannot convert a WhereSelectListIterator object (which is returned) to a MyCustomClass.
I really need the filtered results to be in the same format they came in as. Any suggestions?
If you implement your own Where exthension method you can keep using linq syntax.
public class MyCustomList : List<MyCustomClass>
{
public MyCustomList() : base()
{
}
public MyCustomList(IEnumerable<MyCustomClass> coll) : base(coll)
{
}
}
public static class MyCustomListExtensions
{
public static MyCustomList Where(this MyCustomList myList, Func<MyCustomClass, bool> predicate)
{
return new MyCustomList(Enumerable.Where(myList, predicate));
}
}
public class MyCustomClass
{
public int Int1 { get; set; }
public string Str1 { get; set; }
}
And here I'm using the custom Where implementation:
var myList = new MyCustomList()
{
new MyCustomClass() { Int1 = 1},
new MyCustomClass() { Int1 = 2},
new MyCustomClass() { Int1 = 3},
};
MyCustomList filteredList = from item in myList where item.Int1 > 1 select item;
Assert.AreEqual(2, filteredList.Count);
You have to iterate the list, add them to a collection, and return the collection. Linq doesn't support, directly, conversion of iterators to custom return types other than List, arrays and Dictionaries.

Resources