Skip to content

Instantly share code, notes, and snippets.

@rurounijones
Last active Nov 26, 2020
Embed
What would you like to do?
public class GameContext : DbContext
{
public DbSet<Unit> Units { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseNpgsql("Host=192.168.1.27;Database=tac_scribe;Username=tac_scribe;Password=tac_scribe",
o => o.UseNetTopologySuite())
.UseSnakeCaseNamingConvention();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Unit>()
.Property(b => b.Id).HasColumnName("id");
}
}
public class Unit
{
[Column("id")]
public string Id { get; set; }
[Column(TypeName="geography (point)")]
public Point Position { get; set; }
public double Altitude { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Pilot { get; set; }
public string Group { get; set; }
public int Coalition { get; set; }
public int Heading { get; set; }
public DateTime UpdatedAt { get; set; }
public int Speed { get; set; }
public bool Deleted { get; set; }
public List<Unit> Units { get; } = new List<Unit>();
}
-- Table: public.units
-- DROP TABLE public.units;
CREATE TABLE public.units
(
id text COLLATE pg_catalog."default" NOT NULL,
"position" geography NOT NULL,
altitude double precision NOT NULL DEFAULT 0,
type text COLLATE pg_catalog."default",
name text COLLATE pg_catalog."default",
pilot text COLLATE pg_catalog."default",
"group" text COLLATE pg_catalog."default",
coalition integer NOT NULL,
heading integer,
updated_at timestamp without time zone NOT NULL,
deleted boolean,
speed integer NOT NULL,
CONSTRAINT units_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.units
OWNER to tac_scribe;
@rurounijones
Copy link
Author

rurounijones commented Nov 26, 2020

Table "units" is existing table and has string "id" field as primary key.

EFCore is throwing an exception because it is looking for u.UnitId / u.unit_id (if using the UseSnakeCaseNamingConvention) column despite the Column annotation and the fluent HasColumnName API call.

@rurounijones
Copy link
Author

rurounijones commented Nov 26, 2020

Enabled logging. The above code along with the following select

await using (var db = new GameContext())
{
  var unit = db.Units
  .First();
}

Results in the following SQL which includes a spurious u.unit_id. Looks like some sort of bug with primary key naming

2020-11-27 01:38:12.6703 DEBUG | Main | RurouniJones.DCS.OverlordBot.Overlord.Npgsql | Executing statement(s):
        SELECT u.id, u.altitude, u.coalition, u.deleted, u."group", u.heading, u.name, u.pilot, u.position, u.speed, u.type, u.unit_id, u.updated_at
FROM units AS u
LIMIT 1

This is happening even if we remove all the customisation and have

    public class GameContext : DbContext
    {
        public DbSet<Unit> Units { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseNpgsql("Host=192.168.1.27;Database=tac_scribe;Username=tac_scribe;Password=tac_scribe",
                    o => o.UseNetTopologySuite())
            .UseSnakeCaseNamingConvention();
        }
    }

    public class Unit
    {
        public string Id { get; set; }
        [Column(TypeName="geography (point)")]
        public Point Position { get; set; }
        public double Altitude { get; set; }
        public string Type { get; set; }
        public string Name { get; set; }
        public string Pilot { get; set; }
        public string Group { get; set; }
        public int Coalition { get; set; }
        public int Heading { get; set; }
        public DateTime UpdatedAt { get; set; }
        public int Speed { get; set; }
        public bool Deleted { get; set; }

        public List<Unit> Units { get; } = new List<Unit>();
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment