开发者

LINQ: select an object, but change some properties without creating a new object

I'm trying to select an object using values of another object in LINQ SQL,

I currently have this,

    var result1 = (from s in pdc.ScanLogs
                   from ec in pdc.ExhibitsContacts
                   where s.ExhibitID == ec.ExhibitID
           select ec.Contact);

I want to assign a value of ec.Contact.Note = ec.C开发者_Python百科omment; Is there to a way to do this in LINQ SQL without writing multiple queries?

I read this blog article: http://blog.robvolk.com/2009/05/linq-select-object-but-change-some.html but it doesn't seem to work with LINQ SQL.


Basically you can't do this. LINQ is meant to be a query language, and what you want to do is mutate existing entities with your query. This means your query would have side effects and this is not something that is supported by LINQ to SQL.

While this won't work in a single query while returning LINQ to SQL entities, what will work is when you return simple DTO structues. For instance:

var result1 =
    from s in pdc.ScanLogs
    from ec in s.ExhibitsContacts
    select new ContactDto
    {
        Id = ec.Contact.Id,
        Note = ec.Comment,
        SomeOtherFields = ec.Contact.SomeOtherFields
    };

As a side note: also look at how I removed the where s.ExhibitID == ec.ExhibitID join from the query, by just using the ExhibitsContacts property of the ScanLog entity (which will be generated by LINQ to SQL for you when your database schema has the proper foreign keys defined).


Update:

When you need to return those DTO from several methods, you might consider centralizing the transformation from a collection of entities to a collection of DTO objects. What I tend to do is place this method on the DTO (which makes it easy to find). The code might look like this:

public class ContactDto
{
    // Many public properties here

    public static IQueryable<ContactDto> ToDto(
        IQueryable<Contact> contacts)
    {
        return
            from contact in contacts
            select new ContactDto
            {
                Id = contact.Id,
                Note = contact.ExhibitsContact.Comment,
                ManyOtherFields = contact.ManyOtherFields
            };
    }
}

The trick with this static transformation method is that it takes an IQueryable and returns an IQueryable. This allows to to simply specify the transformation and let LINQ to SQL (or any other LINQ enabled O/RM) to efficiently execute that LINQ expression later on. The original code would now look like this:

IQueryable<Contact> contacts =
    from s in pdc.ScanLogs
    from ec in s.ExhibitsContacts
    select ec.Contact;

IQuerable<ContactDto> result1 = ContactDto.ToDto(contacts);


the problem is that LINQ to SQL does not know how to interpret your extension method. The only way, other than using stored procedures from LINQ to SQL (which kind of defeats the ponit), is to get the object, update and then commit changes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜