2016-08-10 4 views
2

Angenommen, ich habe Datenmodell wie folgt definiert:C# - Entity Framework Code-first - Kartenobjekt in zwei Tabellen

class Geometry 
{ 
    public ICollection<Point> Points { get; set; } 
} 

class Point 
{ 
    public int X { get; set; } 
    public int Y { get; set; } 
} 

Ich möchte es in den folgenden Datenbanktabellen zur Karte:

GeometriesTable 
-- [GeometryId] int, key 
-- [GeometryData] <-- a BLOB here!!! 

PointsTable 
-- [PointId] int, key 
-- [GeometryId] int, foreign key 
-- [X] int 
-- [Y] int 

Meine [GeometryData] BLOB besteht im Wesentlichen aus Punkte-IDs, die die Geometrie und ein paar zusätzliche Meta-Informationen bilden.

die Meta Sachen Wegnehmen, würden diese BLOBs wie folgt aussehen:

[ N (points count) - 4 bytes ] 
[ Points[0].Id  - 4 bytes ] 
[ Points[1].Id  - 4 bytes ] 
[ Points[2].Id  - 4 bytes ] 
... 
[ Points[N-1].Id - 4 bytes ] 

(dh (N + 1) * 4 Byte für jedes BLOB.)

BLOB verwendet wird (statt eine einfache Eins-zu-viele-Beziehung) aus mehreren Leistungsgründen. Das ist etwas, das nicht geändert werden kann.

habe ich die folgenden Einheiten um das Modell zu projizieren:

class GeometryEntity 
{ 
    [Key] 
    [Column("GeometryId")] 
    public int Id { get; set; } 

    [Column("GeometryData")] 
    public byte[] Data { get; set; } 
} 

class PointEntity 
{ 
    [Key] 
    [Column("PointId")] 
    public int Id { get; set; } 

    [Column("GeometryId")] 
    public int GeometryId { get; set; } 

    [Column("X")] 
    public int X { get; set; } 

    [Column("Y")] 
    public int Y { get; set; } 
} 

Nun, vorausgesetzt, ich habe einige IEnumerable<Geometry> ich die Tabellen in der Lage sein möchten, füllen (a DbSet<GeometryEntity> und ein DbSet<PointEntity>). Das spezielle Problem ist, dass ich nicht weiß, wie man Punkt-IDs von PointsTable den entsprechenden Punkte-IDs in meinen Geometrie-BLOBs zuweist.

Irgendwelche Ideen, wie eine Zuordnung wie diese aufgelöst werden könnte? Jetzt

Antwort

1

, vorausgesetzt, ich habe einige IEnumerable<Geometry> ich der Lage zu füllen die Tabellen sein möchten (a DbSet<GeometryEntity> und ein DbSet<PointEntity>).

Ok, das

IEnumerable<Geometry> ProvidedGeometries = 
    new Geometry[] 
    { 
     new Geometry() 
     { 
      Points = new PointEntity[] 
    { 
     new PointEntity() { GeometryId=1, X=1, Y=1, Id = 1}, 
     new PointEntity() { GeometryId=1, X=1, Y=2, Id = 2}, 
     new PointEntity() { GeometryId=1, X=2, Y=1, Id = 3}, 
     new PointEntity() { GeometryId=1, X=2, Y=2, Id = 4} 
    } 
     }, 
    new Geometry() 
     { 
      Points = new PointEntity[] 
    { 
     new PointEntity() { GeometryId=2, X=1, Y=1, Id = 5}, 
     new PointEntity() { GeometryId=2, X=1, Y=2, Id = 6} 
    } 
     } 
    }; 

definieren lassen denke ich, werden die Tabellen der Configuration.Seed mit bevölkern können.

mit dem folgenden Pseudocode

protected override void Seed(YourContext context) 
{ 
    context.GeometryEntities.AddOrUpdate(
     // see the following Linq part 
     ); 

    context.PointEntities.AddOrUpdate(
     // see the following Linq part 
     ); 
} 

oder durch eine Standard-Update mit SaveChanges

using (var ctx = new YourContext()) 
{ 
    ctx.PointEntities.AddRange(Points);  //see below 
    ctx.GeometryEntites.AddRange(Geometries); // " " 
    ctx.SaveChanges(); 
} 

Das besondere Problem ist, dass ich weiß nicht, wie Punkte IDs von der zuweisen PointsTable zu den entsprechenden Punkten IDs in meiner Geometrie BLOBs.

Neben dem spezifischen EF Implementierung Ihrer context, denke ich, dass der folgende Code, den Sie eine Vorstellung von der Linq Teil geben könnte.

IEnumerable<PointEntity> Points =ProvidedGeometries 
        .SelectMany(g => g.Points); 


var geometries = Points.GroupBy(
    p => p.GeometryId, 
    p => BitConverter.GetBytes(p.Id), 
    (id, points) => 
    new GeometryEntity() 
    { 
     Id = id, 
     Data = 
     BitConverter.GetBytes(points.Count()).Concat(
      points.Aggregate((a,b) => a.Concat(b).ToArray()) 
     ).ToArray() 
    } 
    ); 
+0

was genau meinen Sie mit * spezifischer EF-Implementierung *?Ich bin ziemlich neu zu EF selbst und würde wirklich einen Ratschlag schätzen – bashis

+0

@bashis Ok, erhalten: Ich werde versuchen, diese Antwort zu erweitern, indem Sie den EF-Kontext –

+0

Ich denke, Sie müssen die Configuration.Seed überschreiben, um die Tabellen zu füllen und ich habe einen Zeiger auf die bereitgestellten Geometrien als Ausgangspunkt für meine Bearbeitung hinzugefügt. –

Verwandte Themen