【问题标题】:EF 6 Fluent Configuration - recursively nested objects with parent - TPHEF 6 Fluent Configuration - 具有父级的递归嵌套对象 - TPH
【发布时间】:2013-07-15 22:30:43
【问题描述】:

我有以下实体,它有一个自身的集合和一个父属性,如果它是根小部件,我希望它为空:

public class CanvasWidgetQuery
{
    public int CanvasWidgetId { get; set; }

    public int? ParentCanvasWidgetId { get; set; }
    public virtual CanvasWidgetQuery ParentCanvasWidget { get; set; }
    public virtual ICollection<CanvasWidgetQuery> InnerCanvasWidgets { get; set; }

}

因为CanvasWidgetQuery 实际上只是一个基类(也可以是抽象的,但在我看到它在没有它的情况下工作之前我不会放抽象)。我想创建一个通用映射配置来映射CanvasWidgetQuery的派生类型:

public class CanvasWidgetQueryMap<TCanvasWidgetQuery> : EntityTypeConfiguration<TCanvasWidgetQuery>
    where TCanvasWidgetQuery : CanvasWidgetQuery
{
    public CanvasWidgetQueryMap() 
    {
        this.HasKey(q => q.CanvasWidgetId);

        this.HasMany(w => w.InnerCanvasWidgets)
            .WithOptional(w => w.ParentCanvasWidget)
            .HasForeignKey(w => w.ParentCanvasWidgetId);

    }
}

不管派生类型如何,它们都有这些属性,但不幸的是它抱怨WithOptional 调用(一次出现2个错误):

 Error  1   Cannot implicitly convert type 'CanvasWidgetQuery' to 'TCanvasWidgetQuery'. An explicit conversion exists (are you missing a cast?) 


 Error  2   Cannot convert lambda expression to delegate type 'System.Func<CanvasWidgetQuery,TCanvasWidgetQuery>' because some of the return types in the block are not implicitly convertible to the delegate return type  

如果我将其提升到实际派生类型的映射:

 public class SearchCanvasWidgetQueryMap : CanvasWidgetQueryMap<SearchCanvasWidgetQuery>
{
    public SearchCanvasWidgetQueryMap() 
    {
        this.HasMany(w => w.InnerCanvasWidgets)
            .WithOptional(w => w.ParentCanvasWidget)
            .HasForeignKey(w => w.ParentCanvasWidgetId);
    }
}

现在它抱怨它不能同时将CanvasWidgetQuery 隐式转换为SearchCanvasWidgetQuery

public class SearchCanvasWidgetQuery : CanvasWidgetQuery
{

}

我怎样才能完成我所追求的目标

【问题讨论】:

    标签: entity-framework ef-code-first fluent-interface


    【解决方案1】:

    您是否尝试为包含定义层次结构的属性的基类定义映射?

    例如:

    public class CanvasWidgetQueryMap<CanvasWidgetQuery> : EntityTypeConfiguration<CanvasWidgetQuery>
    {
        public CanvasWidgetQueryMap() 
        {
            this.HasKey(q => q.CanvasWidgetId);
    
            this.HasMany(w => w.InnerCanvasWidgets)
                .WithOptional(w => w.ParentCanvasWidget)
                .HasForeignKey(w => w.ParentCanvasWidgetId);
    
        }
    }
    

    这里的答案中有一些很好的附加信息:CTP 4 doesn't consider base class properties 如果上述内容无法实现您的目标,这可能会有所帮助。

    【讨论】:

    • 谢谢,这正是我最终得到的解决方法。但是我越想越明白为什么不应该使用 BaseEntityTypeConfiguration 类在应用程序级别对 EF 中的继承进行建模,因为 CanvasWidgetId 等公共基础属性的配置方式是基于继承策略(TPT、TPC、或 TPH) 而不是配置类的构造函数调用顺序
    • 有趣的是,这鼓励我去阅读更多关于 EF 继承策略的内容,因为我只需要在相当简单的情况下使用 EF 继承。 =D
    猜你喜欢
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 2018-07-24
    • 2023-04-04
    • 2021-05-19
    • 1970-01-01
    相关资源
    最近更新 更多