开发者

Base Types with EntityFramework CodeOnly

开发者 https://www.devze.com 2023-01-19 21:18 出处:网络
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.

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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消