Projection in Linq to SQL and Linq to Entities

余生颓废 提交于 2019-12-20 03:40:54

问题


I am trying to get the columns dynamically. In NHibernate i can do this:

var list = _session.CreateCriteria(typeof(Person))
                   .SetProjection(Projections.ProjectionList()
                   .Add(Projections.Property("FirstName"))
                   .Add(Projections.Property("LastName"))
                   .Add(Projections.Property("Jersey"))
                   .Add(Projections.Property("FortyYard"))
                   .Add(Projections.Property("BenchReps"))
                   .Add(Projections.Property("VertJump"))
                   .Add(Projections.Property("ProShuttle"))
                   .Add(Projections.Property("LongJump"))
                   .Add(Projections.Property("PersonSchoolCollection"))
                    )
                   .SetResultTransformer(new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person)))
                   .List<Person>();

What is the equivalent in Linq?


回答1:


As you also tag linq-to-sql and linq-to-entities I assume you are looking for an equivalent in Linq-to-Sql or Entity Framework. The two answers (so far) would be such equivalents if _session.Query<Person>() were replaced by context.Persons. (Although Darius's answer would throw an exception saying that you can't create entity instances in an entity query).

But apart from the possibility to use Select to create an ad hoc projection, one of the newer features of AutoMapper makes it even easier. Automapper is a very popular tool to map (say: project) a list of types to another list of types. But until recently its drawback was that it only worked on in-memory lists, i.e. the projection did not propagate into the SQL query. So it could not be used to cut back the number of queried fields (as NHibernate projections does).

This problem was described in Stop using AutoMapper in your Data Access Code (the title says it all). But it also offered a preliminary but excellent fix, which was later adopted by Automapper itself.

This feature makes it possible to write very succinct code like:

var dtoList = context.Persons.Project().To<PersonDto>();

(after the mapping between Person and PersonDto was registered in Automapper).

Now the SQL query only contains the fields that are used for PersonDto.




回答2:


Isn't that would work:

 _session.Query<Person>()
         .Select(new {FirstName, LastName, Jersey, FortyYard})
         .ToList()
         .Select(x => new Person() { 
                       FirstName = x.FirstName,
                       LastName = x.LastName, 
                       Jersey = x.Jersey, 
                       FortyYard = x.FortyYard
                 }
          );



回答3:


var list = from person in context.Persons
           select new Person()
           {
               FirstName = person.FirstName,
               LastName = person.LastName,
               Jersey = person.Jersey,
               FortyYard = person.FortyYard,
               BenchReps = person.BenchReps, 
               VertJump = person.VertJump,
               ProShuttle = person.ProShuttle,
               LongJump = person.LongJump,
               PersonSchoolCollection = person.PersonSchoolCollection
           };


来源:https://stackoverflow.com/questions/11621358/projection-in-linq-to-sql-and-linq-to-entities

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!