edmx 映射问题

发布于 2024-11-02 00:13:55 字数 528 浏览 0 评论 0原文

我有一个分支表,其中包含:
company_id、is_deleted、branch_id、branch_name、branch_code

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

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

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

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

I have a Branch table that contains:
company_id, is_deleted, branch_id, branch_name, branch_code

company_id - used in order to determine which company owns the branch.
is_deleted - rows where is_deleted=true are logically deleted and I don't want to return them in my queries.

I have to map thos fields to class Branch. Class Branch have the following members:
BranchId, BranchName, BranchCode

  1. Should I add IsDeleted member in order to map the is_deleted field? Can I filter rows with is_deleted=true if I will not map this field?

  2. Should I add CompanyId member in order to map the company_id field? I have many tables with company_id field since it decide whice company own the row. Can I prevent adding CompanyId member when mapping those tables? When inserting, I need to supply CompanyId - I really prefer to supply it externaly and not from the Branch object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蘸点软妹酱 2024-11-09 00:13:55

现在您有了一个具体的示例,因此我们可以继续讨论您之前的内容问题,我在其中描述了有关映射到现有对象的一些基本信息。

我应该按顺序添加 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
- 我真的更喜欢从外部而不是从分支机构提供
对象。

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

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

我已经回答了描述独立和外国之间的差异的单独问题关键关联

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


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

  • 条件映射(当映射详细信息中 is_deleted = 0 时)
  • 独立关联(我也已经描述过 如何将独立关联更改为外键关联)。如果您要从现有数据库创建模型,您可以在更新向导中选中在模型中包含外键列,它将在整个模型中使用外键关联而不是独立关联。
  • 关系两侧的导航属性
  • 重命名概念模型中的属性(检查映射详细信息,其中好名称映射到数据库名称)
  • 更改 Id 属性设置器的可访问性。我已经回答了类似的问题,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; }
}

So now you have a concrete example so we can continue in discussion from your previous question where I described some basic information about mapping to existing objects.

Should I add IsDeleted member in order
to map the is_deleted field? Can I
filter rows with is_deleted=true if I
will not map this field?

It is possible. It's called conditional mapping where your is_delete column will be used as a filter in the mapping. It has pros and cons:

Pros:

  • The filter is applied every time you query the entity set including a lazy loading and an eager loading. You will never get an entity with is_deleted = 1.

Cons:

  • You can't map is_deleted as a property in the entity. This is one global disadvantage for all columns used to support conditional mapping, table per hierarchy inheritance and independent associations - they can't be exposed as properties. So how would you soft delete your entity if you don't have the column exposed and you can't set it in the application? The only solution for this is stored procedure mapped to delete operation for your entity - btw. it is probably the best solution if you want to do soft / logical deletes because otherwise accidental call of DeleteObject on the context or a set will do hard delete in the database.
  • You can't map multiple conditional entities to the same table. It means you can't have conditionally mapped both undeleted and deleted entity. This can be handled by table per hierarchy inheritance.

Btw. as I know this is not available in DbContext API (EF 4.1).

Should I add CompanyId member in order
to map the company_id field? I have
many tables with company_id field
since it decide which company own the
row. Can I prevent adding CompanyId
member when mapping those tables? When
inserting, I need to supply CompanyId
- I really prefer to supply it externaly and not from the Branch
object.

Do you have a relation between the company table and the branch table in your database? In such case your Branch entity must use either independent or foreign key association with the Company entity. Association by default creates navigation property on both related entities so your Company entity will have collection of related Branches and your Branch will have a reference to the Company it belongs to. Navigation properties are the main way how to create relations in the object world. So if you want the Branch to belong to any Company you will either assign the Company to the property in the Branch or add the Branch to the collection of branches in the Company. That is the theory - it is little bit more complex with EF when using detached objects.

To avoid some problems EFv4 introduced foreign key association where dependent entity doesn't have only navigation property but also foreign key property (your country_id). You can create relation simply by assigning this property with the id of related Country.

I have already answered separate question describing differences between Independent and Foreign key associations.

Conclusion: You must use either navigation property or foreign key property to create relation between object - both these artifacts are mapped in the entity.


Now example which will also show some details you asked me yesterday. This example shows following features:

  • Conditional mapping (When is_deleted = 0 in mapping details)
  • Independent association (I have also already described how to change Independent association to Foreign key association). If you are creating the model from existing database you can check Include foreign key columns in the model in Update wizard and it will use foreign key associations instead of independent associations in the whole model.
  • Navigation properties on both sides of the relation
  • Renaming properties in conceptual model (check mapping details where nice names are mapped to database names)
  • Changing accessibility of the Id property setter. I already answered similar question where this was required with POCO T4 template but same must be done for custom business objects.
  • Support for lazy loading - check virtual keyword used in business object's code for navigation properties.
  • Support for tracking proxies - check virtual keyword used in business object's code for scalar properties.

enter image description here

Related mapped business objects will look like:

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; }
}

And context using these custom business objects can look like:

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; }
}
茶花眉 2024-11-09 00:13:55
  1. 不,如果您想对其执行过滤之类的操作,则需要该字段可见,除非您使用存储过程。

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

  1. No, you're going to need the field visible if you want to do something like filter on it, unless you use Stored Procedures.

  2. I don't really understand this one. Why would you NOT want company_id visible if you need to use it when inserting? It's not going to hurt anything if it's there. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文