I'm currently working on a customer project were I have to store data from the entities in a sqlite DB. I'm working with EF6 and I've chosen the "code first" approach.
Problem: I would like to store geographic coordinates (as single Point in Boo
and as a List of Points in Loo
) as System.Drawing.PointF
in the DB. Because it's not a primitive type it's unfortunately not working like I taught.
Question: What do I have to change in my Entity definition and/or in my Model Configuration to store the single Point of Boo
and also the List of Points of Loo
in the DB? Thank you in advance!
My Entity classes:
public class Collection
{
[Key]
public int Id { get; set; }
public virtual List<Foo> Foos { get; set; }
}
public class Foo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual Collection FooCollection;
}
public class Boo : Foo
{
public PointF Location { get; set; }
}
public class Loo : Foo
{
public List<PointF> Line { get; set; }
}
My Model Configuration:
public class ModelConfiguration
{
public static void Configure(DbModelBuilder modelBuilder)
{
ConfigureFooCollectionEntity(modelBuilder);
}
private static void ConfigureFooCollectionEntity(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Collection>().ToTable("base.MyTable")
.HasRequired(t => t.Foos)
.WithMany()
.WillCascadeOnDelete(false);
}
private static void ConfigureGridElementEntity(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Foo>()
.HasRequired(p => p.FooCollection)
.WithMany(fooCollection => fooCollection.Foos)
.WillCascadeOnDelete(true);
}
}
My DbContext:
public class DbContext : DbContext
{
public DbSet<Collection> DataCollection { get; set; }
public DbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
Configure();
}
public DbContext(DbConnection connection, bool contextOwnsConnection)
: base(connection, contextOwnsConnection)
{
Configure();
}
private void Configure()
{
Configuration.ProxyCreationEnabled = true;
Configuration.LazyLoadingEnabled = true;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
ModelConfiguration.Configure(modelBuilder);
var initializer = new DbInitializer(modelBuilder);
Database.SetInitializer(initializer);
}
}
My DbInitializer:
class DbInitializer :
SqliteDropCreateDatabaseWhenModelChanges<DbContext>
{
public GDbInitializer(DbModelBuilder modelBuilder)
: base(modelBuilder, typeof(CustomHistory))
{ }
}
The easiest way to solve this problem is to work not with System.Drawing.PointF
but with your own point type. This way you are able to give it a ID property and EF can store it as a separate DB-table.
This is how it works for me:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class GeoPoint
{
[Key]
public int Id { get; set; }
public float X { get; set; }
public float Y { get; set; }
[NotMapped]
public PointF GetPointF { get { return new PointF(X, Y); } }
public GeoPoint()
{
X = 0; Y = 0;
}
public GeoPoint(float x, float y)
{
X = x; Y = y;
}
public GeoPoint(PointF point)
{
X = point.X;
Y = point.Y;
}
}