简体   繁体   中英

What is the equivalent of this SQL statement in Linq?

I need to port this SQL statement to LINQ:

SELECT f.ID as IdFlight, 
       Tarif * 1 as Tarif, 
       f.Time, f.TimeOfArrival, 
       sl.Name as FromLoc, 
       sl.Country as FromCountry, 
       sl.Airport as FromAirport,
       dl.Name as ToLoc, 
       dl.Country as ToCountry, 
       dl.Airport as ToAirport 
FROM Flights as f 
    INNER JOIN Locations as sl ON sl.ID = f.ID_Source  
    INNER JOIN Locations as dl ON dl.ID = f.ID_Destination 
    INNER JOIN FlightsTarifs as ftf ON f.Id = ftf.IDFlight 
WHERE f.ID_Destination =30005 AND f.Time <= DATEADD(day,4,'2018/05/24 00:00') 
AND f.Time >= '2018/05/24 00:00' ORDER By f.Time, Tarif

My attempt in Linq:

IQueryable qinfo = from f in context.Flights
                   join sl in context.Locations on f.Id_Source equals sl.ID
                   join dl in context.Locations on f.Id_Destination equals dl.ID
                   join ftf in context.FlightsTarifs on f.ID equals ftf.IDFlight
                   where (f.Id_Source == aFormUser.FlightSrcID)
                   where (f.Id_Destination == aFormUser.FlightDestID)
                   where (f.Time.Date >= aFormUser.DepartureDate.Date)
                   where (f.Time.Date <= aFormUser.DepartureDate.Date.AddDays(4))
                   orderby f.Time, ftf.Tarif
                   select new {f.ID, ftf.Tarif, f.Time, f.TimeOfArrival,
                               sl.Name, sl.Country, sl.Airport,
                               dl.Name, dl.Country, dl.Airport  };

I have some problems to solve now:

  1. Since I am joining the table flights with the table locations twice, in order to get the name of source and of destination locations, doing this in LinQ causes a compiler error, that says dl.Name, dl.Country, dl,Airport are anonymous types and they would end having same name as the others sl.Name, sl.Country, sl.Airport.
  2. I cannot use the "As" expression as I do in Sql or is there any Equivalent one in Linq?
  3. I cannot multiply Tarif by the number of passengers while i am in the linq query, while it does not allow me to do this.

You can use the aliases with the new object initializer with the code below, which will also support multiplying the tarif:

select new {
    f.ID,
    Tarif = ftf.Tarif * 1, // Alias and multiply by your number
    f.Time,
    f.TimeOfArrival,
    SourceName = sl.Name, // Alias
    SourceCountry = sl.Country, // Alias
    SourceAirport = sl.Airport, // Alias
    DestName = dl.Name, // Alias
    DestCountry = dl.Country, // Alias
    DestAirport = dl.Airport // Alias
};

Just to provide a few more details in case others stumble on this, the root cause is that the code was using the new keyword to define an anonymous type with an object initializer that ran into multiple conflicts trying to define the anonymous class (multiple properties with same inferred name, and then unable to name property from expression when tarif was multiplied).

By explicitly naming the properties with conflicts, the compiler no longer had to infer the naming that generated the conflicts.

More: http://geekswithblogs.net/BlackRabbitCoder/archive/2012/06/21/c.net-little-wonders-the-joy-of-anonymous-types.aspx

The link above has some additional examples on how to use the object initializer with anonymous types.

This concept is called Projection , you have to select new anonymous type or alias according to your requirement.

Sample:

var result = data.Select( x => new { FieldName = x.Property } );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM