我正在尝试设置EF以在WCF上工作并保持域类模型EF Agnostic。
代码分为3个项目。 (我正在尝试DDD - 我很陌生,但我很期待学习更多)
Project: QA - Domain Layer. Contains the DataContract models/entities. References QA.Data Project: QA.Data - Data Layer. Contains the context and EDMX (code generation stragtegy = "none") References Entity Framework/System.Data.Entity Project: QA.Repository - Data Access/Repository. Contains the repository classes References QA [Domain Layer] QA.Data [Data Layer] Entity Frame/System.DataEntity
我的理解是域层可以引用数据层,但数据层不应该引用域。这提出的问题是我的域模型/类在域层中定义,但创建并返回它们的上下文位于数据层中。为了让我的上下文知道返回一个“Widget”对象,它需要引用定义“Widget”的Domain层p>
我的(失败的)解决方案:我的解决方案是为每个域模型创建接口并将它们放在数据层中。上下文将返回... IdbSet ......这些接口反过来将由域模型实现,因此保持我的数据层不需要直接引用我的域(这导致非法的循环引用)。域模型最初是使用“ADO.NET DbContext Generator w / WCF Support”T4模板构建的。此过程导致在窗口小部件类定义的开头包含[KnownType(typeof(IWidgetPiece))]。 (一个Widget有一个导航属性...... ICollection ......)
当我尝试访问该服务时出现问题,我收到以下错误
'QA.Data.IWidgetPiece'无法添加到已知类型列表中 另一种类型'System.Object'具有相同的数据协定名称 'http://www.w3.org/2001/XMLSchema:anyType'已经存在。如果 有不同的特定类型的集合 - 例如, 列表和测试[],它们不能同时作为已知类型添加。 请考虑仅指定其中一种类型以添加到已知类型 类型列表。
我可以将这些更改为具体实现... [KnownType(typeof(WidgetPiece))] ...但我继续得到这个错误,因为他们所指的导航属性仍然返回一个IWidgetPiece接口类型,它必须这样做才能满足界面实现。
我试图弄清楚如何保持适当分割的东西,并且仍然有上下文返回它应该的东西。由于这个原因和其他原因,返回上下文的上下文仍然没有与我“坐在一起”,但我想不出另一种方法来做到这一点,甚至这就是上述问题。帮助!
有些代码有希望澄清我以前的谣言......
namespace QA.Data
{
public interface IWidgetPiece
{
String ID { get; set; }
}
public interface IWidget
{
String ID { get; set; }
ICollection<IWidgetPiece> Pieces;
}
public partial class WidgetEntities : DbContext
{
IDbSet<IWidget> Widgets { get; set; }
IDbSet<IWidgetPiece> WidgetPieces { get; set; }
}
}
namespace QA
{
[KnownType(typeof(IWidgetPiece))]
// [KnownType(typeof(WidgetPiece))]
[DataContract(IsReference = true)]
public partial class Widget : QA.Data.IWidget
{
[DataMember]
public String ID { get; set; }
[DataMember]
public virtual ICollection<IWidgetPiece> Pieces { get; set; }
}
[DataContract(IsReference = true)]
public partial class WidgetPiece : QA.Data.IWidgetPiece
{
[DataMember]
public string ID { get; set; }
}
}
namespace QA.Repository
{
public class WidgetRepository
{
public List<Widget> GetWidgetbyID(String sId)
{
WidgetEntities context = new WidgetEntities();
List<IWidget> objs = context.Widgets.Where(b => b.ID == "78").ToList();
List<Widget> widgetList = new List<Widget>();
foreach (var iwidget in widgetList)
widgetList((Widget)iwidget);
return widgetList;
}
}
}
答案 0 :(得分:0)
您真的想要/需要两个独立的模型,即您的数据访问层模型(edmx)和您的“真实”域模型吗?像EF这样的ORM框架的重点在于您可以使用物理(数据库)概念模型之间的映射将域模型映射到数据库表。
从EF4.1开始,您可以构建域模型,然后在数据访问层中使用流畅的API直接映射到数据库。如果您想快速启动,也可以选择从数据库中对POCO域模型进行反向工程。
创建一个完整的EF类模型似乎有点不必要的复杂性,然后只需要将它再次映射到另一个类模型(很可能非常接近EF生成的模型)。