【问题标题】:Code first approach to store System.Drawing.PointF in Sqlite DB将 System.Drawing.PointF 存储在 Sqlite DB 中的代码优先方法
【发布时间】:2017-06-06 07:28:12
【问题描述】:

我目前正在处理一个客户项目,我必须将来自实体的数据存储在 sqlite 数据库中。我正在使用 EF6,我选择了“代码优先”的方法。

问题:我想将地理坐标(Boo 中的单个点和Loo 中的点列表)存储为数据库中的System.Drawing.PointF。因为它不是原始类型,所以很遗憾不能像我教的那样工作。

问题:我必须在我的实体定义和/或模型配置中进行哪些更改才能将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 可能不是最适合地理数据的。EF5 及更高版本对这种东西有一些支持;msdn.microsoft.com/en-US/data/hh859721

标签: c# sqlite entity-framework-6 code-first system.drawing


【解决方案1】:

解决此问题的最简单方法是不使用System.Drawing.PointF,而是使用您自己的点类型。这样你就可以给它一个 ID 属性,EF 可以将它存储为一个单独的数据库表。

这对我来说是这样的:

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

}

【讨论】:

    猜你喜欢
    • 2015-10-19
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    相关资源
    最近更新 更多