关系多对多EF6 Fluent API

我正在使用带有Fluent API的EF6开发应用程序,但是在管理多对多关系时遇到问题。 由于某些内部原因,Join表具有包含4个字段的特定格式 -左ID(FK) -正确编号(FK) -StartDate(dateTime) -EndDate(日期时间)

删除链接实际上是将EndDate设置为非null,但我现在不知道如何在EF6中对其进行配置。 另一方面,在读取链接时,不应考虑使用Not NULL EndDate记录。

能给我一个解决方案吗?

谢谢。

jialinjl 回答:关系多对多EF6 Fluent API

  

能给我一个解决方案吗?

如果链接表中有多余的列,则必须将其建模为实体,并且导航的EndDate逻辑必须明确。 EF不会为您做任何事情。

,

我不想将其设为实体,因为这两个额外字段是技术性字段(出于记录目的),而不是功能性字段。我的应用程序应该不知道它们的存在。

我想知道我是否不能使用MapToProcedure()函数,但是我不知道该怎么做?

,

联接表和EF

EF为您自动化了一些事情。为此,它使用约定优于配置。如果您遵守约定,则可以跳过很多常用配置。

例如,如果您的实体具有名为Id的属性,则EF会固有地假定这是PK。

同样,如果两个实体类型具有相互引用的导航道具(并且两个实体之间仅存在一个直接链接),那么EF会自动假定这些导航道具是单个多对-的两侧许多关系。 EF会在数据库中创建一个联接表,但是它将对您隐藏起来,并让您自己处理这两种实体类型。

  

由于某些内部原因,Join表具有一种特定的格式,包括4个字段-左ID(FK)-右ID(FK)-StartDate(dateTime)-EndDate(datetime)

您的联接表不再符合常规和自动生成的EF联接表的内容。您期望EF不能基于盲目约定提供自定义可配置性,这意味着您必须对此进行显式配置。

第二,您具有这些附加列的事实意味着您希望在某个时候使用此数据(大概是为了显示两个实体之间的历史关系。因此,依靠EF的自动联接表没有任何意义。作为联接表,其内容将从应用程序/开发人员中隐藏。

如果您不需要应用程序提取结束的条目,则第二个考虑因素可能对您无效。但总的说来仍然如此。

这里的解决方案是使联接记录成为其自己的显式实体。本质上,这里您不是在处理多对多关系,而是在处理具有两个一对多关系(两个实体类型中的每一个对应一个关系)的特定实体(join元素)。

这使您能够准确实现所需的目标。在这种情况下,您对EF可以为您实现自动化的期望完全不适用。


软删除

  

删除链接实际上是将EndDate设置为非null,但我现在不知道如何在EF6中对其进行配置。

通常,这被称为“软删除”行为,尽管此处可能稍有不同。在常规的软删除模式中,删除条目后,数据库会秘密保留该条目,但应用程序不知道该条目,因此不会再次看到该条目。

尚不清楚您是否打算将结束条目仍显示在应用程序中,例如关系历史。如果不是这种情况,那么您的情况就是完全软删除行为。

这不是您在模型级别配置的内容,而是您在数据库的SaveChanges行为中覆盖的内容。我如何实现软删除的一个简单示例:

public override int SaveChanges()
{
    // Get all entries of the change trackes (of a given type)
    var entries = ChangeTracker.Entries<IAuditedEntity>().ToList();

    // Filter the entries that are being deleted
    foreach (var entry in entries.Where(entry.State == EntityState.Deleted))
    {
        // Change the entry so it instead updates the entry and does not delete it
        entry.Entity.DeletedOn = DateTime.Now;
        entry.State = EntityState.Modified;
    }

    return base.SaveChanges();
}

这使您可以防止删除想要应用到该实体的实体,这是实现软删除的最安全方法,因为这可以作为来自使用此数据库上下文的任何使用者的数据库删除的全部内容。

您的问题的解决方案几乎相同。假设您为联接实体命名(请参见上一章)JoinEntity

public override int SaveChanges()
{
    var entries = ChangeTracker.Entries<JoinEntity>().ToList();

    // Filter the entries that are being deleted
    foreach (var entry in entries.Where(entry.State == EntityState.Deleted))
    {
        // Change the entry so it instead updates the entry and does not delete it
        entry.Entity.Ended = DateTime.Now;
        entry.State = EntityState.Modified;
    }

    return base.SaveChanges();
}

警告语

软删除通常是所有实体(或至少是数据库的重要对象)的全部内容。因此,有必要像我在此处那样在db上下文级别上捕获它。

但是,如果此实体是唯一的,因为它被软删除,那么它比DAL架构更多的是业务逻辑实现。如果您开始为不同类型的实体编写许多自定义规则,则数据库上下文逻辑将变得混乱不堪,并且不能很好地工作,因为您需要考虑在SaveChanges期间发生的多种可能的操作。

请注意不要将应该是业务逻辑决策的内容推送到DAL。我不能为您画这条线,这取决于您的上下文。但是,请评估数据库上下文是否是实现此行为的最佳位置。

本文链接:https://www.f2er.com/3102454.html

大家都在问