【问题标题】:edmx mapping questionsedmx 映射问题
【发布时间】:2011-08-07 02:56:40
【问题描述】:

我有一个包含以下内容的分支表:
company_id、is_deleted、branch_id、branch_name、branch_code

company_id - 用于确定哪个公司拥有分支机构。
is_deleted - is_deleted=true 的行在逻辑上被删除,我不想在查询中返回它们。

我必须将这些字段映射到类分支。班级分部有以下成员:
BranchId、BranchName、BranchCode

  1. 我应该添加 IsDeleted 成员以映射 is_deleted 字段吗?如果我不映射此字段,是否可以使用 is_deleted=true 过滤行?

  2. 我应该添加 CompanyId 成员以映射 company_id 字段吗?我有很多带有 company_id 字段的表,因为它决定了哪个公司拥有该行。我可以在映射这些表时阻止添加 CompanyId 成员吗?插入时,我需要提供 CompanyId - 我真的更喜欢从外部提供它,而不是从 Branch 对象提供。

【问题讨论】:

  • 如果您可以发布当前的 EDMX 图表并解释导入数据库时​​ Visual Studio 为您创建的默认映射有什么问题,这将有所帮助。
  • 下次我建议你为每个点设置一个问题,因为这些点没有直接关系,它会增加你在这两个问题上得到好的答案的机会。

标签: c# .net entity-framework entity-framework-4 mapping


【解决方案1】:
  1. 不,如果您想对其执行过滤之类的操作,则需要该字段可见,除非您使用存储过程。

  2. 我不太了解这个。如果您需要在插入时使用它,为什么不希望 company_id 可见?如果它在那里,它不会伤害任何东西。 :)

【讨论】:

  • 2.添加 CompanyId 意味着我需要将它添加到我的所有主要元素中,这些元素很多..
【解决方案2】:

现在你有了一个具体的例子,所以我们可以从your previous question 继续讨论,在那里我描述了一些关于映射到现有对象的基本信息。

我是否应该按顺序添加 IsDeleted 成员 映射 is_deleted 字段?我可以吗 如果我使用 is_deleted=true 过滤行 不会映射这个字段?

这是可能的。这称为条件映射,您的is_delete 列将用作映射中的过滤器。它有利有弊:

优点:

  • 每次查询实体集时都会应用过滤器,包括延迟加载和急切加载。你永远不会得到带有is_deleted = 1 的实体。

缺点:

  • 您不能将is_deleted 映射为实体中的属性。这是用于支持条件映射、按层次结构继承表和独立关联的所有列的一个全局缺点——它们不能作为属性公开。那么,如果您没有公开该列并且您无法在应用程序中设置它,您将如何软删除您的实体?唯一的解决方案是存储过程映射到您的实体的删除操作 - 顺便说一句。如果您想进行软/逻辑删除,这可能是最好的解决方案,因为否则在上下文中意外调用 DeleteObject 或集合将在数据库中进行硬删除。
  • 您不能将多个条件实体映射到同一个表。这意味着您不能有条件地映射未删除和已删除的实体。这可以通过按层次结构继承的表来处理。

顺便说一句。据我所知,这在 DbContext API (EF 4.1) 中不可用。

我应该按顺序添加 CompanyId 成员吗 映射 company_id 字段?我有 许多带有 company_id 字段的表 因为它决定了哪家公司拥有 排。我可以阻止添加 CompanyId 映射这些表时的成员?什么时候 插入,我需要提供 CompanyId - 我真的更喜欢从外部而不是从分支机构提供它 对象。

您的数据库中的 company 表和 branch 表之间是否存在关系?在这种情况下,您的Branch 实体必须使用与Company 实体的独立或外键关联。默认情况下,关联会在两个相关实体上创建导航属性,因此您的公司实体将拥有相关分支的集合,并且您的分支将具有对其所属公司的引用。导航属性是如何在对象世界中创建关系的主要方式。因此,如果您希望分公司属于任何公司,您可以将公司分配给分公司的财产,或者将分公司添加到公司的分公司集合中。这就是理论 - 使用分离对象时,EF 稍微复杂一些。

为了避免一些问题,EFv4 引入了外键关联,其中依赖实体不仅具有导航属性,还具有外键属性(您的国家/地区 ID)。您可以通过将此属性分配给相关国家/地区的 id 来简单地创建关系。

我已经回答了描述 differences between Independent and Foreign key associations 的单独问题。

结论:您必须使用导航属性或外键属性来创建对象之间的关系 - 这两个工件都映射到实体中。


现在这个例子也将显示你昨天问我的一些细节。此示例显示以下功能:

  • 条件映射(当映射详细信息中的 is_deleted = 0 时)
  • 独立关联(我也已经描述了how to change Independent association to Foreign key association)。如果您从现有数据库创建模型,您可以在更新向导中选中在模型中包含外键列,它将使用外键关联而不是整个模型中的独立关联。
  • 关系两侧的导航属性
  • 重命名概念模型中的属性(检查好名称映射到数据库名称的映射详细信息)
  • 更改 Id 属性设置器的可访问性。我已经 answered similar question POCO T4 模板要求这样做,但对于自定义业务对象也必须这样做。
  • 支持延迟加载 - 检查业务对象代码中用于导航属性的虚拟关键字。
  • 支持跟踪代理 - 检查业务对象代码中使用的虚拟关键字的标量属性。

相关的映射业务对象如下所示:

public class Branch
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Code { get; set; }
    public virtual Company Company { get; set; }
}

public class Company
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<Branch> Branches { get; set; }
}

使用这些自定义业务对象的上下文可能如下所示:

public class Context : ObjectContext
{
    public Context()
        :base ("name=ModelContainer")
    {
        Companies = CreateObjectSet<Company>();
        Branches = CreateObjectSet<Branch>();

        ContextOptions.LazyLoadingEnabled = true;
        ContextOptions.ProxyCreationEnabled = true;
    }

    public ObjectSet<Company> Companies { get; private set; }
    public ObjectSet<Branch> Branches { get; private set; }
}

【讨论】:

  • 非常感谢您对迟到的回复(节假日)表示歉意。我决定将 CompanyId 保留为外键属性,并且没有导航属性,+ 保留 IsDeleted 以便我在代码中拥有更多的数据控制权。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 2019-01-22
  • 2011-07-28
  • 2010-10-10
  • 1970-01-01
  • 2011-08-16
相关资源
最近更新 更多