在 Sqlite 数据库中存储 System.Drawing.PointF 的代码优先方法
Code first approach to store System.Drawing.PointF in Sqlite DB
我目前正在处理一个客户项目,我必须将来自实体的数据存储在 sqlite 数据库中。我正在使用 EF6,我选择了 "code first" 方法。
问题:我想将地理坐标(作为 Boo
中的单个点和 Loo
中的点列表)存储为数据库中的 System.Drawing.PointF
。因为它不是原始类型,所以不幸的是它没有像我教的那样工作。
问题:我必须在我的模型配置中的实体定义 and/or 中更改什么才能存储 Boo
的单点以及 Loo
的点列表数据库?提前致谢!
我的实体类:
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; }
}
我的模型配置:
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);
}
}
我的 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);
}
}
我的 DbInitializer:
class DbInitializer :
SqliteDropCreateDatabaseWhenModelChanges<DbContext>
{
public GDbInitializer(DbModelBuilder modelBuilder)
: base(modelBuilder, typeof(CustomHistory))
{ }
}
解决此问题的最简单方法是不使用 System.Drawing.PointF
,而是使用您自己的点类型。这样你就可以给它一个 ID 属性 并且 EF 可以将它存储为一个单独的 DB-table.
这对我来说是这样的:
[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;
}
}
我目前正在处理一个客户项目,我必须将来自实体的数据存储在 sqlite 数据库中。我正在使用 EF6,我选择了 "code first" 方法。
问题:我想将地理坐标(作为 Boo
中的单个点和 Loo
中的点列表)存储为数据库中的 System.Drawing.PointF
。因为它不是原始类型,所以不幸的是它没有像我教的那样工作。
问题:我必须在我的模型配置中的实体定义 and/or 中更改什么才能存储 Boo
的单点以及 Loo
的点列表数据库?提前致谢!
我的实体类:
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; }
}
我的模型配置:
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);
}
}
我的 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);
}
}
我的 DbInitializer:
class DbInitializer :
SqliteDropCreateDatabaseWhenModelChanges<DbContext>
{
public GDbInitializer(DbModelBuilder modelBuilder)
: base(modelBuilder, typeof(CustomHistory))
{ }
}
解决此问题的最简单方法是不使用 System.Drawing.PointF
,而是使用您自己的点类型。这样你就可以给它一个 ID 属性 并且 EF 可以将它存储为一个单独的 DB-table.
这对我来说是这样的:
[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;
}
}