Linq: Select an Object and Change Some Properties Without Creating a New Object

LINQ: Select an object and change some properties without creating a new object

I'm not sure what the query syntax is. But here is the expanded LINQ expression example.

var query = someList.Select(x => { x.SomeProp = "foo"; return x; })

What this does is use an anonymous method vs and expression. This allows you to use several statements in one lambda. So you can combine the two operations of setting the property and returning the object into this somewhat succinct method.

LINQ: select certain object properties Into Same object

The only meaningful performance gain, assuming your constructor is "cheap", is in the SQL and data transport from/to.

That said, not everything is about performance. Sometimes it's about clarity, extensibility, decoupling, etc. Clarity wise, you're forcing others to have to ask the question "Is this property used by the UI?"

In addition to clarity issues, you have coupling between the UI and back-end entities. This is not ideal. A cheap/temporary solution might simply be one like this. Keeping in mind that it's still coupled due to the interface on the class, but it's something that would be trivial to adjust in the future if desired.

public interface IMyModel
{
string prop1 { get; set; }
string prop2 { get; set; }
}

public class MyObject : IMyModel
{
public string prop1 { get; set; }
public string prop2 { get; set; }
.....
public string propN { get; set; }
}

IEnumerable<IMyModel> list = context.MyObject
.Select(n => new { n.prop1, n.prop2 }) // only select these properties
.ToArray() // execute the query
.Select(n => (IMyModel)new MyObject { prop1 = n.prop1, prop2 = n.prop2 }); // construct our desired object

Linq select into model and set properties

It's a bit unusual to use a constructor and object initialisation syntax in the same code, to me that's already a code smell.

If I were you, I would create an intermediate list that only gets values from the database, then project that data into your SpecialTaskVm objects. For example:

// First get the data from the database in a simple form we can parse through later
var bookingData = await db.Tasks
.Where(c => c.ClientId == clientId && c.IsDeleted == false && c.Start > startOfThisMonth && c.End < endOfThisMonth)
.OrderBy(x => x.Start)
.Select(x => new // Use an anonymous type
{
Client = x.Client,
Carer = x.Booking.SingleOrDefault(b => b.SlotNumber == 1).Carer,
Carer2 = x.Booking.SingleOrDefault(bk => bk.SlotNumber == 2).Carer
})
.ToListAsync();

// Now we massage the data into a format we can use
var bookings = bookingData
.Select(x => new SpecialTaskVm(new TaskViewModel(x, null))
{
client = x.Client,
carer = x.Carer,
carer2 = x.Carer2
})
.ToList();

Additionally, I would potentially recommend changing the SpecialTaskVm constructor (or add a new one) to include the new fields.

using Task.WhenAll and Linq Select new object

Use async-await in the statement lambda which will make it an async one:

var taskList = dataSource
.Select(async d => new
{
ClientResult = await _client.GetAsync(d.Id),
Id = d.Id,
OtherProperty = d.Other
});

var taskListResult = await Task.WhenAll(taskList);

How to map to another object list with help of linq lambda select

I think your problem is that for each client that is in iteration you retrieve many clients. It should be only one with that id, so methods like First, Single, FirstOrDefault, ... should be used and then you can transform Projects:

//...
Projects = clientsDb.Single(x => x.IdentityId.Equals(client.Id)).Projects.Select(x => new ProjectResponse...

Or, if you have a navigation property between Client and Project you can use it like this:

//...
Projects = client.Projects.Select(x => new ProjectResponse...


Related Topics



Leave a reply



Submit