繁体   English   中英

实体框架5 Fluent API-配置单向关系

[英]Entity Framework 5 Fluent API - Configure Unidirectional Relationship

我无法为自己的生命解决这个问题。 MSDN上的文章尚不清楚,似乎已经过时。 我正在使用EF 5,并且正在尝试为以下各项建立单向关系。 所以这就是我到目前为止所拥有的。

public sealed class Capture {
    /// <summary>
    /// Get and Set Capture's Unique Identifier.
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Get and Set Capture's Operating System.
    /// </summary>
    public OperatingSystem OperatingSystem { get; set; }
}

public sealed class OperatingSystem {
    /// <summary>
    /// Operating System's Unique Identifier.
    /// </summary>
    public int Id { get; set; }
}

internal sealed class EntityCaptureConfiguration : EntityTypeConfiguration<Capture> {
    /// <summary>
    /// Create an Entity Capture Configuration.
    /// </summary>
    public EntityCaptureConfiguration() {
        this.ToTable("Capture");
        this.HasKey(m => m.Id);

        this.Property(m => m.Id).HasColumnName("Id");

        this.HasRequired(m => m.OperatingSystem).WithRequiredDependent().Map(m => {
            m.ToTable("OperatingSystem");
            m.MapKey("OperatingSystemId");
        });
    }
}

编译并运行,我得到以下运行时异常:“ 错误3034:映射片段的问题从第16行开始,第46行:两个可能具有不同键的实体被映射到同一行。确保这两个映射片段映射AssociationSet的两端到相应的列。

我不禁注意到,实际上没有明确的方法表明我想使用2个特定键来联接这2个表。 我的意思是在子表中指定要用于父表联接的键的地方?

这是我需要帮助的:

  1. 我不想公开名为“ OperatingSystemId ”的Capture类型的属性。 OperatingSystem ”属性绰绰有余。

  2. 我不希望CaptureOperatingSystem类型之间存在双向关系。 CaptureOperating System只需单向关系。

  3. 我不想在操作系统表上的数据库中创建名为“ CaptureId ”的列。 我什至不知道为什么需要这样做,但是我在某处阅读了一篇文章建议这样做。

  4. 生成的SQL连接应该是INNER JOIN而不是OUTER JOIN。

  5. 我是否真的需要将Capture类型的OperatingSystem属性定义为虚拟的? 我不希望此属性被延迟加载。

  6. 奖励指向可以向我解释此异常的人,因为我完全迷路了。 对于Fluent API,Google搜索毫无希望。 如果使用设计师,我会受到很多欢迎,但我认为这无关紧要,因为所有结果都建议重新生成模型,我认为这不适用于这里。

更新:我可能对此不太清楚。 我已经在SQL Server中设置了数据库模型。 我试图了解如何使用Fluent API为现有数据库模型配置EF上下文, 而不使用设计器。 我了解,如果我使用设计器,我可以简单地要求它从数据库生成上下文。 那不是我想要的 对于那些好奇的原因-因为我想了解如何使用Fluent API做到这一点。

Update2:因此,如果我在查询中指定了导航属性上的过滤器,那么EF会正确生成联接。 否则,查询中将不会生成任何联接。 无论如何,导航属性仍未填充!

预先感谢一堆。

因此,如果您没有像我这样使用ORM,并且来自使用MyBatis之类的数据映射器或类似工具的背景,那么解决方案就是这样,给出我问题中的示例。

首先,您不必将实体类型声明为密封的,并且将参与关联的任何属性都声明为virtual 这是因为EF会在运行时使用动态代理扩展类型,并使用动态代理覆盖您的属性以启用延迟加载:

public class Capture {
    /// <summary>
    /// Get and Set Capture's Unique Identifier.
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Get and Set Capture's Operating System.
    /// </summary>
    public virtual OperatingSystem OperatingSystem { get; set; }
}

public class OperatingSystem {
    /// <summary>
    /// Operating System's Unique Identifier.
    /// </summary>
    public int Id { get; set; }
}

如果不这样做,则不会引发任何错误,但是EF始终会将您关联的属性设置为null。

其次,除非您的关联属性尚未配置用于映射,否则不要将其映射到特定表,因为EF会抱怨同一表实际上被映射了两次。 在我的示例中,我已经自己映射了OperatingSystem类型,并且在建立关联时,我再次对其进行了映射:

internal sealed class EntityCaptureConfiguration : EntityTypeConfiguration<Capture> {
    /// <summary>
    /// Create an Entity Capture Configuration.
    /// </summary>
    public EntityCaptureConfiguration() {
        this.ToTable("Capture");
        this.HasKey(m => m.Id);

        this.Property(m => m.Id).HasColumnName("Id");

        this.HasRequired(m => m.OperatingSystem).WithRequiredDependent().Map(m => m.MapKey("OperatingSystemId"));
    }
}

最后,如果您必须绝对将实体类型声明为密封的,并且不想将任何属性声明为虚拟的(无论如何都不能使用密封的类型),请在上下文的配置中禁用代理和延迟加载:

public sealed class EntityDefaultContext : DbContext {    
    /// <summary>
    /// Model Creating Event Handler.
    /// </summary>
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        var entityCaptureConfiguration = new EntityCaptureConfiguration();
        var entityOperatingSystemConfiguration = new EntityOperatingSystemConfiguration();

        modelBuilder.Configurations.Add(entityOperatingSystemConfiguration);
        modelBuilder.Configurations.Add(entityCaptureConfiguration);

        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }
}

那是所有人。 我希望这对以后像我这样的人有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM