具有共享实体的

时间:2016-09-01 16:00:45

标签: c# asp.net inheritance entity-framework-6 dbcontext

我认为情况相当简单,但事实证明这很困难。

我有一个数据库,目前有两个不同的Web应用程序使用它。每个应用程序都有专门用于该应用程序的表,而且还有几个共享的表,例如ApplicationUser表。

我要做的是拥有一个basecontext,它将拥有所有共享实体,并具有源自basecontext的特定于应用程序的上下文。对于应用程序上下文,许多共享实体将具有一个派生的特定于应用程序的实体,该实体具有其他导航属性。

我会试着说清楚:

共享库中的BaseContext

public class BaseContext : DbContext
{
    public DbSet<ApplicationUser> ApplicationUsers { get; set; }
}

App1中的App1Context

public class App1Context : BaseContext
{
    public new DbSet<App1User> ApplicationUsers { get; set; }
}

public class App1User: ApplicationUser
{ 
    //Navigation property specific to App1
    public virtual ICollection<SomeApp1Entity> SomeApp1Entity_Creator { get; set; } 
}

App2中的App2Context

public class App2Context : BaseContext
{
    public new DbSet<App2User> ApplicationUsers { get; set; }
}

public class App2User: ApplicationUser
{
    //Navigation property specific to App2
    public virtual ICollection<SomeApp2Entity> SomeApp2Entity_Creator { get; set; } 
}

BaseContext有一个用于ApplicationUser的dbset。

App1Context有一个App1User的dbset,它派生自ApplicationUser。

App2Context有一个App2User的dbset,它也派生自ApplicationUser。

我需要特定于应用程序的用户实体,因为App1User可能具有未共享的实体的导航属性,并且仅适用于App1。 App2User也是如此。

我想要BaseContext的主要原因是我可以使用一个SharedService,它使用这个上下文并且拥有我的所有ApplicationUser方法用于CRUD。

我尝试了几种变体,所以如果有必要,我可以提供更多信息,我只是不想让这个问题太长,试图解释我尝试过的所有内容。

我知道我想要dbset用于BaseContext,以便我可以拥有共享服务。在App1Context中构建模型时,我尝试忽略ApplicationUser,因为我认为会使用App1User,但这不起作用。当我这样做时,它表示没有键集(因为它忽略了具有键的基类,而不是在派生类中拾取它)。当我不忽略时,我得到一个关于鉴别器列的错误。

我的第一个问题是,我是否完全在浪费时间?甚至可以使用Entity Framework 6.3吗?

如果可能的话,我怎么能以不同的方式找到解决方案?

另外,让我补充一点,我首先使用代码,但不担心迁移。数据库已经存在,数据库的所有更改都在那里进行,然后在C#代码中相应地实现。

1 个答案:

答案 0 :(得分:1)

我不确定这是否是你要找的:

我将共享的上下文和实体保存在一个单独的库中 - SharedDbContext 命名空间:

namespace SharedDataContext
{
    public class BaseDbContext : DbContext
    {
        public BaseDbContext() : base("CFConnection")
        { }

        public DbSet<ApplicationUser> ApplicationUsers { get; set; }

    }

    public partial class ApplicationUser
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

创建了两个应用程序 - WebApplication1 WebApplication2

WebApplication1 - App1Context - 有自己的实体Country与共享 ApplicationUser 的外键关系

namespace WebApplication1
{
    public class App1Context : BaseDbContext
    {
        public DbSet<Country> Countries { get; set; }
    }

    public class Country
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int ApplicationUserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
    }
}

WebApplication1 - App2Context - 拥有自己的实体City,与共享的 ApplicationUser 具有外键关系

namespace WebApplication2
{
    public class App2Context : BaseDbContext
    {
        public DbSet<City> Cities { get; set; }
    }

    public class City
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int ApplicationUserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
    }

}

WebApplication2的示例控制器和结果:

namespace WebApplication2.Controllers
{
    public class CityController : ApiController
    {
        public IEnumerable<City> Get()
        {
            IEnumerable<City> cities;
            using (var context = new App2Context())
            {
                cities = context.Cities.Include(c => c.ApplicationUser).ToList();
            }
            return cities;
        }
    }
}

共享实体详细信息的结果:

enter image description here

我建议在共享实体中保留与上下文相关的导航,而不是从另一端查询 - 如果您需要获取&#34; User1&#34;的城市,请查询DbSet<City> Cities的{​​{1}}(如果我们ApplicationUserId == 1ICollection<City> ApplicationUser这很容易,我不确定如何在这种情况下实现< / em>的)