2016-09-01 3 views
0

У меня есть ситуация, которая, по моему мнению, была бы довольно простой, но мне сложно.BaseDbContext с общими объектами

У меня есть одна база данных, в которой в настоящее время используется два разных веб-приложения. Каждое приложение имеет таблицы, которые используются специально для этого приложения, в то время как есть также несколько разделяемых таблиц, таких как таблица ApplicationUser.

То, что я пытаюсь сделать, это иметь базовый текст, который будет иметь все общие сущности и иметь специфические для приложения контексты, которые основаны на basecontext. Для контекстов приложения многие из общих объектов затем будут иметь производную специфическую для приложения сущность, которая обладает дополнительными свойствами навигации.

Я попытаюсь проиллюстрировать для ясности:

BaseContext в общей библиотеке

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

App1Context в App1

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

App2Context в App2

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

BaseCon текст имеет dbset для ApplicationUser.

App1Context имеет dbset для App1User, который является производным от ApplicationUser.

App2Context имеет dbset для App2User, который также является производным от ApplicationUser.

Мне нужны конкретные пользовательские объекты приложения, поскольку App1User может иметь свойство навигации для сущности, которая не является общей, и применяется только к App1. То же самое касается App2User.

Основная причина, по которой я хочу использовать BaseContext, заключается в том, что у меня есть SharedService, который использует этот контекст и имеет все мои методы ApplicationUser для CRUD.

Я пробовал несколько вариантов, поэтому при необходимости могу предоставить дополнительную информацию, я просто не хочу слишком долго задавать этот вопрос, пытаясь объяснить все, что я пробовал.

Я знаю, что я хочу dbset для BaseContext, чтобы у меня была общая служба. При создании модели в App1Context я попытался игнорировать ApplicationUser, так как я думал бы, что App1User будет использоваться вместо этого, но это не сработает. Когда я это делаю, он говорит, что нет набора ключей (потому что он игнорирует базовый класс, который имеет ключ, а не выбирает его в производном классе). Когда я не игнорирую, я получаю сообщение об столбце дискриминатора.

Мой первый вопрос: я полностью трачу свое время на этот подход? Возможно ли это с помощью Entity Framework 6.3?

Если возможно, как я могу пойти по-другому, чтобы найти решение?

Кроме того, позвольте мне добавить, что сначала использую код, но не беспокоюсь о миграции. База данных уже существует, и все изменения в базе данных сделаны там, а затем реализованы соответственно в коде C#.

+0

Возможно ли это: 'public class BaseContext: DbContext {DbSet Users {get; задавать; } открытый класс App1Context: BaseContext {} и открытый класс App2Context: BaseContext {} '. Как правило, мы указываем все навигационные свойства из объекта User? Обычно другие объекты будут иметь навигационное свойство пользователя для установления отношений, таких как updatedBy, CreatedBy и т. Д. – Developer

+0

Это здорово, если вы сможете отформатировать вопрос – Eldho

+0

Будет ли работать базовый класс? 'BaseContext : DbContext, где TUser: ApplicationUser' и' App1Context: BaseContext '. –

ответ

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:

WebAp plication1 - App1Context - Имеет свою собственное лицо Страну с внешним ключом отношению к общим 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 - имеет свою собственную сущность Город с внешним ключом отношению к общим 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

Я хотел бы предложить не в контексте хранения связанных плаваний в общих сущностях, а запрашивать у него с другим конца - Если вам нужно получить города из «user1» запрос к DbSet<City> Cities для ApplicationUserId == 1 (это было бы легко, если бы мы ICollection<City> внутри ApplicationUser который я не знаю, как достичь в этом случае)

+0

Спасибо за макет! Я действительно надеялся сделать то, что вы предлагали не делать.Имейте App1User с конкретными ICollections App1. App1User будет получен из ApplicationUser. Как и вы, я не знаю, как это сделать, когда это сработает. Похоже, это было бы прямо, но EF это не нравится. Я бы предпочел запросить с другого конца, чем повторить весь общий код для каждого приложения, поэтому я продолжу и реализую, как вы предложили. Большое спасибо за Ваш ответ. – user2023116

Смежные вопросы