具有实体框架和空间数据的持久无知域

Posted

技术标签:

【中文标题】具有实体框架和空间数据的持久无知域【英文标题】:Persistent Ignorant Domain with Entity Framework and Spacial Data 【发布时间】:2015-10-28 19:37:15 【问题描述】:

我正在开发一个实现 DDD 和存储库模式的应用程序,如下图所示:

我希望保持我的领域层持久无知,所以我不想在那里安装实体框架库。我面临的唯一问题是我的应用程序使用空间数据,但我不应该使用 DbGeography 作为我的实体的属性类型,一旦它属于来自 EntityFramework 程序集的 System.Data.Entity.Spatial 命名空间。

有没有办法创建一个类来保存域层中的纬度、经度和海拔值,就像这样:

public class Location

    public double Latitude  get; set; 
    public double Longitude  get; set; 
    public double Elevation  get; set; 

然后在我的 Repository Layer 中将该类转换为 DbGeography?

换句话说,域实体将只有 Location 类作为属性:

public class Place : IEntityBase, ILocalizable

    public int Id  get; set; 
    public string Name  get; set; 
    public Location Location  get; set; 
    public User Owner  get; set; 

我会将其转换为 DbGegraphy 以保留空间数据并仅在存储库层进行一些计算。我的计划是尝试这样的转换:

public class LocationMap : ComplexTypeConfiguration<Location>

    public LocationMap()
    
        Property(l => DbGeography.FromText(string.Format("POINT(0 1)", l.Longitude, l.Latitude))).HasColumnName("Location");
        Ignore(l => l.Elevation);
        Ignore(l => l.Latitude);
        Ignore(l => l.Longitude);
    

但它不起作用,而且永远不会。我该如何解决这个问题?在这种情况下有哪些最佳做法?

谢谢

【问题讨论】:

嗨@GertArnold,请看一下。 msdn.microsoft.com/pt-br/library/…. 应用架构做得很好,顺便说一句。 @GertArnold,对于 EF6,DbGeography 和 DbGeometry 等空间类已从 System.Data.Spatial 移至 System.Data.Entity.Spatial。 msdn.microsoft.com/en-US/data/dn469466 啊,错过了,谢谢。恐怕您必须直接映射到 DbGeography。您可以做的最好的事情是将 EF 实体映射到域实体。是的,它是一个额外的映射层,但无论如何都很难将 DDD 原则应用于 EF 类模型。 @LucasS。据我所知,Entity Framework 不是 DDD 的理想 ORM 候选者。我会看看 NHibernate 之类的东西,它不需要在域模型中做出任何妥协(或很少妥协),或者考虑使用没有阻抗不匹配的写入模型的数据库。 【参考方案1】:

嗯,我不知道“正确”的方式,但是,我有一个棘手的想法。我希望它会对您有所帮助或提供更多变体: Ypu 有域实体Place,它是完全持久无知的,它位于域组件中。好的。 让我们在 Repository 程序集中再创建一个 Place 类:

internal sealed class EFPlace : Place

    DbGeography EFLocation 
    
        get
        
            return DbGeography.FromText(string.Format("POINT(0 1)", Location.Longitude, Location.Latitude);
        
        set
        
            //vice versa convertion, I don't know, how to do it :)
        
    

我们为实体框架创建了特殊的类,并映射它:

public class PlaceMap : ComplexTypeConfiguration<EFPlace>

    public PlaceMap ()
    
        Property(p => p.EFLocation).HasColumnName("Location");
        Ignore(p => p.Location);
    

但是,我们必须在保存到存储库时从 Place 转换为 EFPlace。您可以创建特殊的构造函数或强制转换方法。 另一个变体 - 在域和存储库程序集中创建部分类放置。并在 Repository 一类中添加所需的属性,依此类推。 好吧,它看起来很难看 :( 但是,我不知道 Persistent Ignorant Domain 的“纯”真实示例。我们总是有实体框架的局限性。NHibernate 有更多的功能。

【讨论】:

以上是关于具有实体框架和空间数据的持久无知域的主要内容,如果未能解决你的问题,请参考以下文章

实体框架和 ASP.NET 的最佳实践

在 MySQL 数据库上运行迁移时出现实体框架错误。 “空间/全文/哈希索引和显式索引顺序的错误使用”

创建索引时,具有mysql数据库迁移的实体框架失败

实体框架空间聚合函数

持久性无知和 DDD 现实

实体框架:为啥对象数组类型的属性没有持久化到数据库?