2016-08-10 6 views
2

Предполагая, что у меня есть данные модели, определенные как это:C# - Entity Framework кода первая - карта объекта на две таблицы

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

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

Я хотел бы, чтобы отобразить его в следующих таблицах базы данных:

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

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

My [GeometryData] BLOB в основном состоит из идентификаторов точек, которые составляют геометрию и пару дополнительных метаинформаций.

Принимая мету вещь прочь, этот BLOB-бы выглядеть следующим образом:

[ 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 ] 

(то есть (N + 1) * 4 байта для каждого BLOB.)

BLOB используется (вместо простое отношение «один ко многим») для нескольких причин производительности. Это то, что нельзя изменить.

Я создал следующие объекты спроецировать модель:

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; } 
} 

Теперь, если у меня есть некоторые IEnumerable<Geometry> Я хотел бы иметь возможность заполнить таблицы (а DbSet<GeometryEntity> и DbSet<PointEntity>). Конкретная проблема заключается в том, что я не знаю, как назначить идентификаторы точек из PointsTable в соответствующие идентификаторы точек в моих BLOB-объектах геометрии.

Любые идеи о том, как такое отображение может быть разрешено?

ответ

1

Теперь, если у меня есть некоторые IEnumerable<Geometry> Я хотел бы быть в состоянии для заполнения таблиц (а DbSet<GeometryEntity> и DbSet<PointEntity>).

Ok, давайте определим

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} 
    } 
     } 
    }; 

Я думаю, что вы можете заполнить таблицы с помощью Configuration.Seed.

со следующим кодом псевдо

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

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

или стандартного обновления с SaveChanges

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

Конкретная проблема в том, что я не знаю, как присвоить идентификаторы точек из PointsTable к соответствующим точкам ID в моей геометрии BLOB.

Кроме конкретных EF реализации в вашего context, я думаю, что следующий код мог бы дать вам представление о части Linq.

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

что именно вы подразумеваете под * конкретный EF осуществление *?Я совершенно новичок в EF и очень ценю совет: – bashis

+0

@bashis Хорошо, получилось: я попытаюсь расширить этот ответ, добавив контекст EF –

+0

Думаю, вам нужно переопределить конфигурацию.Seed для заполнения таблиц и я добавил указатель на предоставленные геометрии в качестве отправной точки в моем редактировании. –