代码之家  ›  专栏  ›  技术社区  ›  Paul Meems

npgsql,ef6,nts:EntityType“point”未定义键

  •  0
  • Paul Meems  · 技术社区  · 7 年前

    我正在为.NET Framework 4.7编写一个简单的导入工具,用于读取MS Access文件并将其保存到PostGIS数据库中。

    我现在很难让EF6 Point 对象是NetTopology类,而不是另一个表。

    当我从Postgis数据库中读取写入数据时,会得到以下错误:

    System.Data.Entity.ModelConfiguration.ModelValidationException
      HResult=0x80131500
      Message=One or more validation errors were detected during model generation:
    
    Importer.Point: : EntityType 'Point' has no key defined. Define the key for this EntityType.
    Points: EntityType: EntitySet 'Points' is based on type 'Point' that has no keys defined.
    

    下面是一些代码:

        public static void Main(string[] args)
        {
            // Place this at the beginning of your program to use NetTopologySuite everywhere (recommended)
            NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();
    
            using (var context = new PostGisContext())
            {
                var newKey = context.MyLocations.Count();
            }
        }
    

    context.MyLocations.Count() 正在引发错误。

    public class PostGisContext : DbContext
    {
        public DbSet<MyLocation> MyLocations { get; set; }
    
        public PostGisContext() : base("name=PostgreSql")
        {        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // PostgreSQL uses the data schema by default - not dbo.
            modelBuilder.HasDefaultSchema("data");
    
            // Don't use plural table names:
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    
            // Change CamelCase to lower-case:
            modelBuilder.Types().Configure(c => c.ToTable(LowerCaseTableName(c.ClrType)));
    
            modelBuilder.Conventions.Add(new LowerCaseConvention());
    
            base.OnModelCreating(modelBuilder);
        }
    
        private static string LowerCaseTableName(Type type)
        {
            var result = Regex.Replace(type.Name, ".[A-Z]", m => m.Value[0] + "_" + m.Value[1]);
    
            return result.ToLower();
        }
    }
    
    // A custom convention.
    internal class LowerCaseConvention : IStoreModelConvention<EdmProperty>
    {
        public void Apply(EdmProperty property, DbModel model)
        {
            property.Name = Regex.Replace(property.Name, ".[A-Z]", m => m.Value[0] + "_" + m.Value[1]).ToLower();
        }
    }
    

    当改变 Location 列到字符串上面的代码工作正常。

    public class MyLocation
    {
        [Key] 
        public int Id { get; set; }
        public string LocationId { get; set; }
        public NetTopologySuite.Geometries.Point Location { get; set; }
    } 
    
    public class NpgSqlConfiguration : DbConfiguration
    {
        public NpgSqlConfiguration()
        {
            const string name = "Npgsql";
    
            SetProviderFactory(providerInvariantName: name, 
                providerFactory: NpgsqlFactory.Instance);
    
            SetProviderServices(providerInvariantName: name, 
                provider: NpgsqlServices.Instance);
    
            SetDefaultConnectionFactory(connectionFactory: new NpgsqlConnectionFactory());
        }
    }
    

    我肯定忘了一个场景或什么,但我找不到。 任何帮助都将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Shay Rojansky    7 年前

    实体框架6不支持NetTopologySuite和PostGIS,只支持实体框架核心。这是因为EF6的类型系统是关闭的,不允许像EFCore那样灵活地进行特定于提供者的扩展。