C# SQL & LINK fråga
Skulle du kunna lägga in tabellstrukturen och dina entities + DbContext så att vi kan verifiera om det fungerar med tex. MSSQL.
Bara genom att titta på frågan så tycker jag att det borde fungera.
Jag har skapat databasen manuellt med Postgres först (för övnings skull), och sedan kört "Scaffold" för att skapa DbContext och Entitys.
CREATE TABLE airports (
id integer,
ident character varying(10),
type character varying(30),
name character varying(150),
iso_country character varying(5),
latitude_deg numeric,
longitude_deg numeric,
elevation_ft integer,
continent character varying(30),
iso_region character varying(8),
municipality character varying(150),
gps_code character varying(10),
iata_code character varying(10),
local_code character varying(10),
home_link character varying(150),
wikipedia_link character varying(150)
);
CREATE TABLE runways (
id integer,
airport_ref integer,
airport_ident character varying(10),
length_ft integer,
width_ft integer,
surface character varying(150),
lighted boolean,
closed boolean,
le_ident character varying(10),
le_latitude_deg numeric,
le_longitude_deg numeric,
le_elevation_ft numeric,
le_heading_degt numeric,
le_displaced_threshold_ft integer,
he_ident character varying(10),
he_latitude_deg numeric,
he_longitude_deg numeric,
he_elevation_ft numeric,
he_heading_degt numeric,
he_displaced_threshold_ft integer
);
public partial class Airport
{
public int? Id { get; set; }
public string Ident { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string IsoCountry { get; set; }
public decimal? LatitudeDeg { get; set; }
public decimal? LongitudeDeg { get; set; }
public int? ElevationFt { get; set; }
public string Continent { get; set; }
public string IsoRegion { get; set; }
public string Municipality { get; set; }
public string GpsCode { get; set; }
public string IataCode { get; set; }
public string LocalCode { get; set; }
public string HomeLink { get; set; }
public string WikipediaLink { get; set; }
}
public partial class Runway
{
public int? Id { get; set; }
public int? AirportRef { get; set; }
public string AirportIdent { get; set; }
public int? LengthFt { get; set; }
public int? WidthFt { get; set; }
public string Surface { get; set; }
public bool? Lighted { get; set; }
public bool? Closed { get; set; }
public string LeIdent { get; set; }
public decimal? LeLatitudeDeg { get; set; }
public decimal? LeLongitudeDeg { get; set; }
public decimal? LeElevationFt { get; set; }
public decimal? LeHeadingDegt { get; set; }
public int? LeDisplacedThresholdFt { get; set; }
public string HeIdent { get; set; }
public decimal? HeLatitudeDeg { get; set; }
public decimal? HeLongitudeDeg { get; set; }
public decimal? HeElevationFt { get; set; }
public decimal? HeHeadingDegt { get; set; }
public int? HeDisplacedThresholdFt { get; set; }
}
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
#nullable disable
namespace MetarApi.Domain
{
public partial class metarContext : DbContext
{
public metarContext()
{
}
public metarContext(DbContextOptions<metarContext> options)
: base(options)
{
}
public virtual DbSet<Airport> Airports { get; set; }
public virtual DbSet<Runway> Runways { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseNpgsql("Host=localhost;Database=metar;Username=test;Password=SUPERHEMLIGT");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("Relational:Collation", "en_US.utf8");
modelBuilder.Entity<Airport>(entity =>
{
entity.HasNoKey();
entity.ToTable("airports");
entity.Property(e => e.Continent)
.HasMaxLength(30)
.HasColumnName("continent");
entity.Property(e => e.ElevationFt).HasColumnName("elevation_ft");
entity.Property(e => e.GpsCode)
.HasMaxLength(10)
.HasColumnName("gps_code");
entity.Property(e => e.HomeLink)
.HasMaxLength(150)
.HasColumnName("home_link");
entity.Property(e => e.IataCode)
.HasMaxLength(10)
.HasColumnName("iata_code");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Ident)
.HasMaxLength(10)
.HasColumnName("ident");
entity.Property(e => e.IsoCountry)
.HasMaxLength(5)
.HasColumnName("iso_country");
entity.Property(e => e.IsoRegion)
.HasMaxLength(8)
.HasColumnName("iso_region");
entity.Property(e => e.LatitudeDeg).HasColumnName("latitude_deg");
entity.Property(e => e.LocalCode)
.HasMaxLength(10)
.HasColumnName("local_code");
entity.Property(e => e.LongitudeDeg).HasColumnName("longitude_deg");
entity.Property(e => e.Municipality)
.HasMaxLength(150)
.HasColumnName("municipality");
entity.Property(e => e.Name)
.HasMaxLength(150)
.HasColumnName("name");
entity.Property(e => e.Type)
.HasMaxLength(30)
.HasColumnName("type");
entity.Property(e => e.WikipediaLink)
.HasMaxLength(150)
.HasColumnName("wikipedia_link");
});
modelBuilder.Entity<Runway>(entity =>
{
entity.HasNoKey();
entity.ToTable("runways");
entity.Property(e => e.AirportIdent)
.HasMaxLength(10)
.HasColumnName("airport_ident");
entity.Property(e => e.AirportRef).HasColumnName("airport_ref");
entity.Property(e => e.Closed).HasColumnName("closed");
entity.Property(e => e.HeDisplacedThresholdFt).HasColumnName("he_displaced_threshold_ft");
entity.Property(e => e.HeElevationFt).HasColumnName("he_elevation_ft");
entity.Property(e => e.HeHeadingDegt).HasColumnName("he_heading_degt");
entity.Property(e => e.HeIdent)
.HasMaxLength(10)
.HasColumnName("he_ident");
entity.Property(e => e.HeLatitudeDeg).HasColumnName("he_latitude_deg");
entity.Property(e => e.HeLongitudeDeg).HasColumnName("he_longitude_deg");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.LeDisplacedThresholdFt).HasColumnName("le_displaced_threshold_ft");
entity.Property(e => e.LeElevationFt).HasColumnName("le_elevation_ft");
entity.Property(e => e.LeHeadingDegt).HasColumnName("le_heading_degt");
entity.Property(e => e.LeIdent)
.HasMaxLength(10)
.HasColumnName("le_ident");
entity.Property(e => e.LeLatitudeDeg).HasColumnName("le_latitude_deg");
entity.Property(e => e.LeLongitudeDeg).HasColumnName("le_longitude_deg");
entity.Property(e => e.LengthFt).HasColumnName("length_ft");
entity.Property(e => e.Lighted).HasColumnName("lighted");
entity.Property(e => e.Surface)
.HasMaxLength(150)
.HasColumnName("surface");
entity.Property(e => e.WidthFt).HasColumnName("width_ft");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
Jag håller på med ett litet hobbyprojekt för att försöka lära mig ASP.NET.
Har fastnat lite med LINQ och SQL, jag använder PGSQL för att koppla EF CORE till en Postgresql databas.
I databasen har jag två "tables", en med flygplatser och en med landningsbanor.
Jag vill göra query efter en viss flygplats kopplat till dess identifieringskod, och sedan göra en "JOIN" med alla landningsbanor som har samma flygplats-id.
Det bästa jag lyckats knacka ihop är detta:
var airportData = (from airport in DbAirports.Airports
where airport.Ident == "ESSA"
join runway in DbAirports.Runways on airport.Ident equals runway.AirportIdent into runways
select new { airport, runways });
Detta ger dock följande felkod
"could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'."
Om jag lägger till .ToList() efter DbAirports.Airports fungerar det. Hittar dock inga andra exempel där folk gjort så i själva queryn. Tänker att det påverkar prestandan?
Är det kanske att jag använder Postgres med EF CORE som ställer till det?
Precis som felmeddelandet säger så behöver den på något sätt kompilera din linq-sats till en faktiskt exekvering. Annars så kommer din airportData bara innehålla ett linq expression och ingen data.
Nu vet jag inte vad du har kollat på för andra källor där folk bygger upp sina frågor med LINQ. Men stegen ser ut så här:
Hämta datakälla
Bygg frågan (query)
Körfrågan mot datakällan
Mer kan du hitta hos Microsoft, i deras docs-site
Nu är det länge sedan jag gjorde någonting med LINQ och EF, men jag vill minnas att idiomatiskt sätt att lösa det här på är att sätta upp relationer i databasen och sedan instruera LINQ att hämta ut dessa via Include().
Så:
1) I databasen skapa en foreign key från Runway.AirportIdent till Airport.Ident
2) Kör om scaffolding
3) Nu borde dina modeller i C# innehålla referenser mellan klasserna, Airport borde ha en "List<Runway> Runways" och Runway borde ha en "Airport Airport".
Skriv om din Query som:
DbAirports.Airports.Include(a => a.Runways).ToList();
Exempel på navigation properties.
namespace EFCoreSample26
{
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
// using nuget package Microsoft.EntityFrameworkCore.SqlServer
// using nuget package Microsoft.Data.SqlClient
internal class Program
{
private static void Main()
{
const string host = "(LocalDB)\\MSSQLLocalDB";
const string database = "flight_sample";
var connectionString = $"Data Source={host};Initial Catalog={database};Integrated Security=True;";
var dbContextBuilder = new DbContextOptionsBuilder<FlightContext>();
dbContextBuilder.UseSqlServer(connectionString);
using var db = new FlightContext(dbContextBuilder.Options);
// note: no need to join because we have navigation properties instead
// get the first airport (since name is not unique we can get multiple airports)
// named "essa" and includes the runways
var airport = db.Airports
.Where(x=> x.Name == "essa")
.Include(x => x.Runways)
.FirstOrDefault();
// get the actual airport with short name (is unique) "es" and includes the runways
var uniqueAirport = db.Airports
.Where(x => x.ShortName == "es")
.Include(x => x.Runways)
.FirstOrDefault();
// get all airports named "essa" and includes the runways
var airports = db.Airports
.Where(x => x.Name == "essa")
.Include(x => x.Runways);
}
}
public class FlightContext : DbContext
{
public FlightContext(DbContextOptions<FlightContext> options)
: base(options)
{
// empty..
}
public virtual DbSet<Airport> Airports { get; set; }
}
[Index(nameof(ShortName), IsUnique = true)]
public class Airport
{
public int Id { get; set; }
public string Name { get; set; }
public string ShortName { get; set; }
public ICollection<Runway> Runways { get; set; }
}
public class Runway
{
public int Id { get; set; }
public string Name { get; set; }
public int AirportId { get; set; }
public Airport Airport { get; set; }
}
}
Stort tack för flera bra svar, ska leka runt med era förslag och se vilket jag fastnar för!
- Idag Spara till ditt nästa RTX-kort – med en RTX-spargris 22
- 20 / 9 Nvidia kan sluta tillverka RTX 4090 i oktober 30
- 20 / 9 Samsung S24 Ultra slår Iphone 16 Pro Max i batteritest 48
- 20 / 9 Guide: Cybenetics vs 80 Plus – lär känna PSU-certifieringarna 37
- 20 / 9 Rykte: Playstation 6 kan släppas i två versioner 47
- Igår Microsoft ska återstarta olycksdrabbat kärnkraftverk 53
- Igår Krönika: Reklam kommer döda Youtube som kunskapskälla 50
- Igår Kraftiga prishöjningar väntar Youtube Premium 226
- Igår Helgsnack: Hur prioriterar du komponentköp? 40
- 20 / 9 Vinnarna i TCL-tävlingen korade – olja, rymd och fjäll på prispallen! 8
- ASUS TUF GAMING B650-PLUS WIFI - Heads up!19
- Saftiga systemkrav för Flight Simulator 202426
- Köpråd GPU 1080p, budget ~4k41
- Spara till ditt nästa RTX-kort – med en RTX-spargris23
- Någon som kommer köpa Wooting 80 he=14
- Grabben vill ha ny dator - tips och värdering6
- 4070 TI Super eller 4080 Super?1
- Bästa grafikkortsköpet i september 202461
- köpråd angående wifi-router4
- Vad lyssnar du på just nu?14364
- Säljes Komplett dator
- Köpes Intel moderkort
- Säljes 2 st. 27” 4K UHD LG UltraFine 27UP850-W
- Säljes Gskill Ripjaws 2x16gb B-die
- Köpes Mitx delar eftersökes chassi Gpu Cpu mm
- Köpes Z690 eller Z790 samt 32Gb
- Säljes Källarrensning
- Säljes Optiplex 3090 10500t, 16gb ram, 256gb ssd
- Säljes Dator | Utan GPU | 7800X3D | 32GB DDR5 |
- Säljes Spelkod - Välj 2 spel (Avatar, Starfield, Lies of P, CoH 3)
- Saftiga systemkrav för Flight Simulator 202426
- Spara till ditt nästa RTX-kort – med en RTX-spargris23
- Stor förändring på gång i DirectX14
- Microsoft ska återstarta olycksdrabbat kärnkraftverk53
- Krönika: Reklam kommer döda Youtube som kunskapskälla50
- Kraftiga prishöjningar väntar Youtube Premium225
- Helgsnack: Hur prioriterar du komponentköp?40
- Microsoft släpper ”Windows‑appen”22
- Nvidia kan sluta tillverka RTX 4090 i oktober30
- Samsung S24 Ultra slår Iphone 16 Pro Max i batteritest48
Externa nyheter
Spelnyheter från FZ
- Rykte: Det nedlagda Concord har kostat Sony 400 miljoner dollar idag
- Skepp Ohoj! Like a Dragon: Pirate Yakuza in Hawaii har avtäckts idag
- Netflix smyger ut en teaser för Splinter Cell: Deathwatch idag
- Xbox 13 år gamla ambassadörprogram stängs ned i oktober igår
- Kingdom Hearts 4 kommer ge oss ett avslut på serien igår