I'm beginner to .NET but I'm fairly familiar with building webapplications using 3 tier architecture. I usually have a webapplication project for the webforms and a wpf application project to keep my Domain, Controller and Data Access Layer classes.
I'm familiar with creating a DbContext class and using it to deal with the database through EF. I've added .NET Identity to my webapplication project but I need to make changes to the identity user and add more data to it.
I'm following this tutorial to accomplish this but it is intended for MVC. I have 2 seperate context files at the moment, one for identity and other for my usual purposes. is there a way I can have one context?
my DbContext looks like,
namespace ExammerCore.Infrastructure
{
class ExammerContext : DbContext
{
public ExammerContext()
: base("DefaultConnection")
{
}
}
}
the identity DbContext I made using the tutorial looks like,
namespace ExammerCore.Infrastructure
{
class IdentityContext : IdentityDbContext<ApplicationUser>
{
public IdentityContext()
: base("DefaultConnection")
{
}
}
}
My IdentityModels.cs looks like,
namespace ExammerCore.Domain
{
public class ApplicationUser : IdentityUser
{
//You can extend this class by adding additional fields like Birthday
public string BirthDate { get; set; }
}
}
how can I blend these two together to have one DbContext class? or is there another way to add custom fields to a user without inheriting Identity classes?
My solution structure looks like this,
Solution structure
I've googled a lot haven't found an answer.
Change the line
class ExammerContext : DbContext
to
class ExammerContext : IdentityDbContext<ApplicationUser>
to pull all the Identity DbSets into your ExammerContext
in your dbcontext you should have properties that represent what entities get used to build tables.... that should look something like this...
class ExammerContext : DbContext
{
public IDbSet<ApplicationUser> ApplicationUsers { get; set; }
// add other classes/tables here.
public ExammerContext()
: base("DefaultConnection")
{
}
}
this way you will only need your context.
Related
In my solution I have two projects: SharePoint and Class Library. In ClassLibrary is a class DBContext and models. "Enable-Migration" generated class Configuration.cs. Next, I created the first migration through the "Add-Migration Initialize" and it worked. My next step was to "Update-Database" everything was fine. But after a while I changed the model and I wanted to generate migration. Unfortunately, I get a blank method Up and Down. Entity Framework does not see my changes ... The models are written without annotations and Context it inherits DbContext and is written like this:
public class SchoolContext: DbContext
{
public SchoolContext (): base () {}
public DbSet <Student> Students;
}
Models are written in this way:
public class Student
{
public int FirstName {get; set; }
}
When I program using LINQ with a .dbml file, there is only one context. But, when I do an MVC site, it seems like I have separate contexts for each entity (which is the way the MVC tutorial showed me how to do it; with "movies" context).
I have:
public class AccountsContext : DbContext
{
public AccountsContext()
: base("DefaultConnection")
{
}
public DbSet<Account> Accounts { get; set; }
}
And, I have:
public class ClientsContext : DbContext
{
public ClientsContext()
: base("DefaultConnection")
{
}
public DbSet<Client> Clients { get; set; }
}
When I call these, I have to create separate contexts, like:
private AccountsContext db = new AccountsContext();
private ClientsContext clientsContext = new ClientsContext();
... Which is both annoying, and it seems redundant since I know that when I use LINQ, I only have to instantiate a single database object.
Is there a way to use only one contextŠ± and is this recommended?
There shouldn't be anything stopping you from using one context. The database, and the tooling used to access it, should be completely independent of anything outside of it (business logic, service layer, UI, etc...).
The number of contexts, or how you use them, shouldn't change based on your client technology.
What about MVC leads you to believe that you would need more than one context? And what's stopping you from doing so?
If you think you need to use a context for each entity, because the sample was that way, you don't. Just use one context.
If it helps, this is what a simple context looks like with more than one entity:
public partial class abook_dbEntities : DbContext
{
public abook_dbEntities()
: base("name=abook_dbEntities")
{
}
public DbSet<Entity> Entities { get; set; }
public DbSet<Contact> Contacts { get; set; }
}
If it helps, a typical business flow looks like this:
UI -> Controller -> Business logic -> Data access -> Database
Your data contexts would go in your data layer. Your logic would go in your business logic layer.
Im creating a class library that will be used in several projects. This library includes a handfull of entities with associated tables in the database. My question is: how do I create these tables when I include this library in a project?
I suspect you want a library of objects that are used to generate a database?
If so you can achieve this with EntityFramework CodeFirst.
At minimum you'll need your objects and a DbContext.
a typical set up maybe as follows:
Entities
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}
DbContext
public class MyDbContext : System.Data.Entity.DbContext {
public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
public DbSet<Person> People { get; set; }
}
These would live in your project and when you add a reference to it, for example a web project. There are different ways to build the Database, you could call the constructor (MyDbContext) from your web project and pass a connection string to a server.
I have a DLL with a base model using code first EF 4.3.
What i want is to extend certain models in that dll with additional fields.
for example in BaseModel.DLL
namespace BaseModel
{
public class Account
{
public Id { get;set;}
public string Name {get;set;}
}
}
in a referencing project i want to extend the Account model (and DB table):
public class Account : BaseModel.Account
{
public string SomeAdditionalInfo { get;set;}
}
I want to end up with a table Account with fields
Id
Name
SomeAdditionalInfo
This way i can keep reusing the BaseModel (and logic) in several similar projects.
I guess i can't use partial classes because we're speaking different DLL's.
Maybe inheritance? I tried several ways but i keep getting conflicts about having 2 models with the same name.
Any hints? tips? solutions?
You can use inheritance though Table per Hierarchy.
You can create base class AccountBase and child class Account:AccountBase:
public class AccountBase
{
public Id { get;set;}
public string Name {get;set;}
}
public class Account : AccountBase
{
public string SomeAdditionalInfo { get;set;}
}
It generates Table AccountBase that will contains columns Id, Name, SomeAdditionalInfo
There will be also column Discriminator that will contains instance of what class contains in this row.
In many projects I have to make a table containing users and implementing standard user-based functions such as authentication, saving, etc. So I decided to make a class library containing these functionalities, for example:
public class User
{
public int? Id {get;set;}
public string UserName {get;set;}
public string Password {get;set;}
}
public class MyDbContext : DbContext
{
public DbSet<User> {get;set;}
}
public class UserService
{
public MyDbContext Context {get;set;} // will be initialized in constructor
public User GetByUserName(string username)
{
return (from s in Context.Users where s.UserName.Equals(username) select s).SingleOrDefault();
}
// etc...
}
Now when I start a new Mvc project I add this library and extends the DbContext with custom models. The problem is I don't know how to extend the User table with some additional fields, for example:
public class MyUser : User
{
public bool IsApproved {get;set;}
}
public class CustomDbContext : MyDbContext
{
public DbSet<SomeOtherModel> {get;set;}
// problem: override DbSet in MyDbContext with class MyUser?
//public DbSet<MyUser> {get;set;}
}
In this case I also need to override the DbSet<User> of the MyDbContext. If I remove the DbSet<User> in the library my UserService class won't work anymore. Any ideas how to make an extensible framework?
You could use generics (I haven't tested this, just a thought):
public abstract class UserDbContext<TUser> : DbContext where TUser : User
{
public DbSet<TUser> Users {get;set;}
}
And then inherit:
public class CustomDbContext : MyDbContext<MyUser>
And the same generic in the UserService:
public abstract class UserService<TUser> where TUser : User
{
public UserDbContext<TUser> Context {get;set;} // will be initialized in constructor
public TUser GetByUserName(string username)
{
return (from s in Context.Users where s.UserName.Equals(username) select s).SingleOrDefault();
}
// etc...
}
Don't inherit from User, instead make User a partial class and extend User that way. That only works if your library is just a set of source files, and not compiled into an assembly.
EDIT:
Another option is to simply not define the dbcontext in your framework, and define it using your library classes in your application project. You could then call an initialization function in your framework to do the mappings you need and call it from OnModelCreating.
You could always use composition and have MyUser contain a User property. Then, you would have a brand-new DbContext that would have a DbSet.
This would create two tables in the database, but is probably the easiest. (disclaimer: haven't tried this and you may encounter cross-assembly issues)