EntityFramework CodeOnly 的基本类型

发布于 2024-09-27 04:47:35 字数 2128 浏览 6 评论 0原文

我在实体框架的仅代码模型中遇到了很多“基本类型”问题。我在实体框架的仅代码模型中遇到了很多“基本类型”问题。

当我尝试使用带有 DbSet

A 导航属性“Flags”映射到两个不同的联接表“page.flags”和“template.flags”。导航属性只能存在一种映射

这对我来说意味着我无法映射继承的属性。这对许多面向对象的代码设计来说是相当大的破坏。有已知的补救措施吗?我意识到我可以使布局变得非抽象,并为其提供支持,但很明显这不是领域模型的意图。抽象类是基础,而不是存储的模型。

我想补充一点,如果我将 IList 放入 Template 类中,则此代码将运行。即使通过继承,Id 字段仍然有效。我不明白为什么会发生这种情况。有人可以启发我吗?

public abstract class Layout
{
    public virtual int Id
    {
        get;
        set;
    }

    public virtual IList<Flag> Flags
    {
        get;
        set;
    }
}

public class Template : Layout
{
    public virtual string Name
    {
        get;
        set;
    }
}

public class Page: Layout
{
}

public class LayoutConfiguration : EntityConfiguration<Layout>
{
    public LayoutConfiguration()
    {
        HasKey(u => u.Id);
        Property(u => u.Id).IsIdentity();

        MapHierarchy().Case<Page>(c => new
        {
            c.Id
        }).ToTable("Pages");

        MapHierarchy().Case<Template>(c => new
        {
            c.Id,
            c.Name
        }).ToTable("Templates");
    }
}
public class TemplateConfiguration : EntityConfiguration<Template>
{
    public TemplateConfiguration()
    {
        Property(o => o.Name).HasMaxLength(64).IsUnicode();

        HasMany(u => u.Flags).WithOptional()
            .Map("template.flags",
            (template, flag) => new {
                Template = template.Id,
                Flag = flag.Id
            });

        MapSingleType(c => new {
            c.Id,
            c.Name
        }).ToTable("templates");
    }
}

public class PageConfiguration : EntityConfiguration<Page>
{
    public PageConfiguration()
    {
        HasMany(c => c.Flags).WithOptional()
            .Map("page.flags",
            (page, flag) => new
            {
                Page = page.Id,
                Flag = flag.Id
            });
    }
}

I am having a lot of trouble with 'base types' in the Code Only model of the Entity Framework. I am having a lot of trouble with 'base types' in the Code Only model of the Entity Framework.

When I try to run this code using a DbContext with a DbSet<Template>, I get the following error.

A The navigation property 'Flags' is mapped to two different join tables 'page.flags' and 'template.flags'. Only one mapping of the navigation property may exist

What this says to me is that I cannot map inherited properties. This is quite breaking to a lot of object oriented code design. Is there a known remedy? I realize I can make Layout non-abstract, and have a backing for it, but it's very obvious this is not the intention of the domain model. The abstract class is a foundational base, not the stored model.

I would like to add, if I put the IList<Flag> in the Template class, this code runs. The Id field still works, even through inheritance. I do not understand why this is happening. Can someone enlighten me?

public abstract class Layout
{
    public virtual int Id
    {
        get;
        set;
    }

    public virtual IList<Flag> Flags
    {
        get;
        set;
    }
}

public class Template : Layout
{
    public virtual string Name
    {
        get;
        set;
    }
}

public class Page: Layout
{
}

public class LayoutConfiguration : EntityConfiguration<Layout>
{
    public LayoutConfiguration()
    {
        HasKey(u => u.Id);
        Property(u => u.Id).IsIdentity();

        MapHierarchy().Case<Page>(c => new
        {
            c.Id
        }).ToTable("Pages");

        MapHierarchy().Case<Template>(c => new
        {
            c.Id,
            c.Name
        }).ToTable("Templates");
    }
}
public class TemplateConfiguration : EntityConfiguration<Template>
{
    public TemplateConfiguration()
    {
        Property(o => o.Name).HasMaxLength(64).IsUnicode();

        HasMany(u => u.Flags).WithOptional()
            .Map("template.flags",
            (template, flag) => new {
                Template = template.Id,
                Flag = flag.Id
            });

        MapSingleType(c => new {
            c.Id,
            c.Name
        }).ToTable("templates");
    }
}

public class PageConfiguration : EntityConfiguration<Page>
{
    public PageConfiguration()
    {
        HasMany(c => c.Flags).WithOptional()
            .Map("page.flags",
            (page, flag) => new
            {
                Page = page.Id,
                Flag = flag.Id
            });
    }
}

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

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

发布评论

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

评论(1

胡渣熟男 2024-10-04 04:47:35

当您为模板实体使用基类型时,您还必须在映射中对此继承进行建模。这意味着您必须为布局编写配置(将映射 ID 和标志),并为模板编写配置(将映射名称)。 EF 中有多种映射继承的方法。您可能应该检查每个层次结构的表。

编辑:根据您的评论,您正在寻找每个类的表 + CTP4 的示例

编辑2:好的。我使用抽象父类中定义的导航属性测试了您的场景,如果您尝试将其映射到多个表,它确实不起作用。

When you use base type for your Template entity, you also have to model this inheritance in mapping. It means that you have to write configuration for Layout which will map Id and Flags and configuration for Template which will map Name. There is several approaches of mapping inheritance in EF. You should probably check Table per Hiearchy.

Edit: Based on your comment you are looking for Table per Class + examples for CTP4.

Edit2: Ok. I tested your scenario with navigation property defined in abstract parent class and it really doesn't work if you are trying to map it to multiple tables.

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