ORM可以与实体框架一起使用吗?

时间:2011-07-06 19:45:01

标签: .net database entity-framework orm

我们正在尝试使用EF在我们的域实体和我们的表之间使用ORM实现数据层。我们已成功完成了与其各自表格非常相似的域实体的琐碎映射,但在尝试使用包含外键在其表格表示中的更复杂关系的对象时遇到了绊脚石。我发现大量引用“表拆分”使用EF与共享主键的表,但我们的架构不是这种情况。

作为一个例子,我想将域实体作为POCO,而不是简单ID的数据层意识:

public class EntityInfo
{
    public int EntityId { get; set; }
    public string EntityName { get; set; }
    public string TypeName { get; set; }
    public string ComponentName { get; set; }
}

public class Entity
{
    public int EntityId { get; set; }
    public EntityType Type { get; set; }
    public EntitySource Source { get; set; }
    public string Name { get; set; }
}

public class EntityType
{
    public int TypeId { get; set; }
    public string Name { get; set; }
}

public class EntitySource
{
    public int SourceId { get; set; }
    public string Name { get; set; }
}

这些将映射到一系列具有外键的等效表:

Table Entities:
[PK]    int     EntityId
[FK]    int     TypeId
[FK]    int     SourceId
        string  Name

Table EntityTypes:
[PK]    int     TypeId
        string  Name

Table EntitySources:
[PK]    int     SourceId
        string  Name

我们真正想做的是将表格表示与域实体完全分开,并实现映射层(.msl)来解决这些有些复杂的关系。尽管没有自己的直接表表示,上面的EntityInfo类将从表构建并存储到表中。是否可以使用.msl进行这样的映射(多个表到对象层次结构)? EF有可能吗?

2 个答案:

答案 0 :(得分:0)

IIRC实体框架1.0不允许实体与表格分离。但我相信你能用EF 4.0做到这一点

答案 1 :(得分:0)

你至少尝试过吗?您呈现的模型中没有复杂的映射。这是一对多关系的最基本映射。只需在设计器中打开EDMX并运行Update from database命令(从上下文菜单中)。在向导中选择三个表,并取消选中将外键添加到模型的选项。

编辑:

是实体框架甚至能够映射您的EntityInfo对象,但该对象将被只读,因为它包含的所有相关实体(它们的FK关系)的所有信息都将丢失。有两种方法可以映射它:

  • 在SSDL中使用DefiningQueryDefiningQuery是用于加载要映射的列的自定义SQL。 EF不会打扰您加入多少个表来获取结果集。问题是默认设计器每次尝试从数据库更新模型时都会删除DefiningQuery
  • 在MSL中使用QueryViewQueryView是映射到新enttiy的自定义实体SQL视图。它建立在模型中定义的实体之上。因此,您还必须映射EntityEntityTypeEntitySource(但您可以将它们设置为数据汇编内部的内容)。 QueryView在数据库中保存更新。

必须在EDMX中直接定义DefiningQueryQueryView(由XML打开),因为设计人员不支持它们。这些功能在代码优先方法中不可用。这些功能创建了只读实体,因此如果您还需要CUD操作,则必须创建存储过程并将它们映射到新创建的实体。

还有最常用的最后一个选项 - 您可以创建linq-to-entities查询,只需将映射的实体投影到未映射的EntityInfo

var infos = context.Entities
                   .Select(e => new EntityInfo
                        {
                            EntityId = e.EntityId,
                            EntityName = e.Name,
                            TypeName = e.Type.Name,
                            ComponentName = e.Source.Name 
                        });