I am making an intranet website using ASP.NET MVC and SQL Server 2012. I am making a repository and architecturing with Onion Architecture. My problem is that the company in which I am working, already has several Server DBs in which the tables have no relations between each other. Instead, there are tables to map these relations. For example a table User, and a table Document have a table User_joint_Document to make a relation, containing both IDs (IDDocument and IDUser). Now when I write my generic repository:
class Repository<T> : IRepository<T> where T : class
the problem is the Generic type T makes no sense and I can't affect values in my model using EF queries which is normal, and what would be great would be to have a parent class BaseEntity to have IDs defined for each tables, then I can write:
class Repository<T> : IRepository<T> where T : BaseEntity
And all my table models would inherit from BaseEntity. But that would also mean rewriting the whole DB in a relational manner and mapping every DB POCO manually(correct me if I'm wrong), and I do not have the skillset to do this(there are over 300 tables in the different server DBs and I lack proper knowledge and experience to do this kind of operation).
Is there a way to keep my original DB structure, and still write a Generic Repository? How would one go about doing this?
EDIT To clarify my question because @saeb answered partially to my question. Can I have a generic repo without having a parent class for my DB POCOs? Or do I need it in order to then have only ONE repository to rule them all? For example:
class Repository<T>:IRepository<T> where T : class
{
private readonly ApplicationContext context;
private DbSet<T> entities;
public Repository(PrincipalServerContext context)
{
this.context = context;
entities = context.Set<T>();
}
public T Get(long id)
{
return entities.SingleOrDefault(s => s.IDUser == id);
//This does not work, IDUser isn't recognized
}
Thanks for your help!
... has several Server DBs in which the tables have no relations between each other ...
But they do have a relationship, a Many-to-Many relationship, which is defined via that third mapping table (whether that's a correctly defined relationship is another topic)
... the problem is the Generic type T makes no sense and I can't affect values in my model using EF queries ...
Why doesn't it and why can't you? considering your table examples, you'd have two entities, User
and Document
and they'd look like this:
public class User
{
public int IDUser { get; set; }
public virtual ICollection<Document> Documents { get; set; }
...
}
public class Document
{
public int IDDocument { get; set; }
public virtual ICollection<User> Users { get; set; }
...
}
And you can use the fluent API in your context's OnModelCreating
to set up the relationship via the third table:
public class YourContext: DbContext
{
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany<Document>(u => u.Documents)
.WithMany(d => d.Users)
.Map(userJointDocument =>
{
userJointDocument.MapLeftKey("IDUser");
userJointDocument.MapRightKey("IDDocument");
userJointDocument.ToTable("User_joint_Document");
});
}
...
}
And then you can query User
s and Document
s in your repository as you would if there was a direct relationship between them. Here are more good sources to learn more about this if you like.