I have my Accountmodels.cs class like this---
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
public class RegisterExternalLoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
public string ExternalLoginData { get; set; }
}
and my User Profile class is like this---
public class UserProfile
{
public UserProfile()
{
this.Posts = new HashSet<Post>();
}
public int UserId { get; set; }
public string UserName { get; set; }
public string AvatarExt { get; set; }
public virtual ICollection<Post> Posts { get; set; }
and finally my dbContext class is----
public class WallEntities : DbContext
{
public WallEntities()
: base("name=WallEntities")
{
}
public DbSet<Post> Posts { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
I am using both WallEntities and DefaultConnection as name in connection string.I am using Simple Membership so i have a InitializeSimpleMembershipAttribute.cs File.Its look like this---
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
Database.SetInitializer<UsersContext>(null);
try
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}.
My Problem is that It is creating two tables in Sql server.One is UserProfile and another is UserProfiles table.I want to create only 1 table that is UserProfile table with UserId,UserName and AvatarExt Property.After registration, it should store all information.
I want to answer my question is it may be useful for someone---
Just The problem here was not to use the two DbContext.Instead of that, for the code First approach one dbContext is enough.
So, DbContext should be like this----
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<Post> Posts { get; set; }
it should not be here
// public DbSet<UserProfile> UserProfiles { get; set; }
}
and romove that WallEntities DbContext. and reomove USerFrofile from UserContext as i have commented out and also change all the corresponding codes in the same way.
Related
[Table("User")]
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string UserName { get; set; }
//I should join with User.UserName and UserRoles.UserName
public List<UserRoles> UserRolesList { get; set; }
}
[Table("Role")]
public class Role
{
public int Id { get; set; }
public string RoleKey { get; set; }
public string Description { get; set; }
}
[Table("UserRoles")]
public class UserRoles
{
public int Id { get; set; }
public string UserName { get; set; }
public string RoleKey { get; set; }
}
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<UserRoles> UserRolesList { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
//Getting all users with roles
var usersWithRoles= _dbContext.Users.Include(b => b.UserRolesList).ToList();
I have 3 tables (User,Role and UserRoles), I want to joins User and UserRoles table with UserName column. But EntityFramework not allow doing this with out primary key column. What should I do?
Thanks.
I think you should design the UserRole table like below
[Table("UserRoles")]
public class UserRoles
{
public int Id { get; set; }
public int UserId { get; set; }
public int RoleId { get; set; }
public User User {get; set;}
public Role Role {get;set;}
}
Using thing you can now join with userId and get the user name from user table. Also can join with role table by roleId and can get role key.
I have made one model so far and added controller using EF, and made some list of books
public class Books
{
public string ImageUr { get; set; }
public string BookTitle { get; set; }
public string ShortDescription { get; set; }
public decimal Price { get; set; }
public string Author { get; set; }
public int ID { get; set; }
}
public class BooksDBContext : DbContext
{
public DbSet<Books> Book { get; set; }
}
and im displaying that list in this action:
public ActionResult Books()
{
return View(db.Book.ToList());
}
and my question is how can i make another model or database that will be passed into this action (viewpage for news about new books for example):
public ActionResult News()
{
View(db.News.ToList());
}
and the model for news to be something like this:
public class News
{
public string Title{ get; set; }
public string Subtitle { get; set; }
public string Content{ get; set; }
public int ID { get; set; }
}
Well maybe you can try out a viewmodel. When I started learning ASP.NET MVC I did the tutorial Working with data and learned a lot about entity framework and ASP.NET MVC! I will give you a link. ASP.NET working with data
For your solution some code:
UPDATE You will need some virtual properties in your classes to define the relationships: we have a one to many relationship because book can have more news items and news can only have one book.
public class Book //change your class name to book
{
public string ImageUr { get; set; }
public string BookTitle { get; set; }
public string ShortDescription { get; set; }
public decimal Price { get; set; }
public string Author { get; set; }
public int ID { get; set; }
public int NewsId { get; set; }
public virtual ICollection<News> News { get; set; }
}
public class News
{
public string Title{ get; set; }
public string Subtitle { get; set; }
public string Content{ get; set; }
public int ID { get; set; }
public int BookId {get; set; }
public virtual Book Book { get; set; }
}
if your want to use a viewmodel then add a new folder named viewmodels and add a new class
public class BookNewsViewmodel //viewmodel of book and News :)
{
public IEnumerable<Book> Books { get; set; }
public IEnumerable<News> News { get; set; }
}
In the DbContext
namespace yourProject.DAL
{
public class yourProjectContext : DbContext //this is a DbContext!
{
public yourProjectContext () : base("yourProjectContext") //A constructor
{
}
public DbSet<Book> Books { get; set; } //make a DbSet of your classes
public DbSet<News> News { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Pluralize your tablenames from Books to Book and from Newss to News :)
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
In your controller:
With viewmodel
public ActionResult BookNewsIndex()
{
var viewModel = new BookNewsViewmodel();
viewModel.Books = db.Books
.Include(n => n.News)
return View(viewModel.ToList()); //return your data.ToList() to your view
}
Without a viewmodel
public ActionResult BookNewsIndex()
{
var data = db.Books.Include(n => n.News);
return View(data.ToList()); //return your data.ToList() to your view
}
In your View named BookNewsIndex you can do this. I am not sure about this but you can give it a try
#model yourproject.ViewModels.BookNewsViewmodel for your viewmodel
OR
#model IEnumerable<yourProject.Models.Book> without viewmodel
with viewmodel
#model.Books.ShortDescription
#model.News.Subtitle
without viewmodel
#Model.First().ShortDescription get something from your book!
#Model.First().News.First().Subtitle get something from news!
In part 7 of the tutorial he will use a viewmodel
I hope this will help you!
This has nothing to do with MVC, but with Entity Framework.
You'll have to add the DbSet for News:
public class BooksDBContext : DbContext
{
public DbSet<Books> Book { get; set; }
public DbSet<News> News { get; set; }
}
I have those 2 Models
public class BranchEmployees
{
public int ID { get; set; }
[Required, Column(Order = 0), Key]
public string ApplicationUserID { get; set; }
[Required, Column(Order = 1), Key]
public int BranchID { get; set; }
public virtual ICollection<ApplicationUser> ApplicationUser { get; set; }
public virtual ICollection<Branch> Branch { get; set; }
}
public class Branch
{
public int ID { get; set; }
public string BranchName { get; set; }
[Required]
public string ApplicationUserID { get; set; }
public ApplicationUser User { get; set; }
public virtual ICollection<BranchEmployees> BranchEmployees { get; set; }
}
public class ApplicationUser
{
//rest of the code
}
UPDATE
I have everything set up but what I want is the query that gets me the Employees whose IDs are in the branch employees table
, I'm using entity framework code first with MVC 5 , how do I do it ?
Assuming that your ApplicationUser class will have a navigational property called BranchEmployees, here is the query that gets me the Employees whose IDs are in the branch employees table
List<ApplicationUsers> employeeNames =
dbContext
.ApplicationUsers
.Where(au => au.BranchEmployees
.Count() > 0).ToList();
Also, can you provide whole model including ApplicationUser? I also wonder why you do not prefer BranchEmployees to inherit from ApplicationUser.
You don't need a class that indicates a many-to-many relation between two tables when you do code-first. The key here is to create virtual properties of those classes. Lets say you have a class Student and class Course. Students can be in many Courses and Courses can have many Students. To generate a database using these models the classes should look like this:
public class Student
{
private ICollection<Course> _courses;
public Student()
{
this._courses = new HashSet<Course>();
}
[Key]
public int Id { get; set; }
public string FullName { get; set; }
public virtual ICollection<Course> Courses
{
get { return this._courses; }
set { this._courses = value; }
}
}
And for Course:
public class Course
{
private ICollection<Student> _students;
public Course()
{
this._students = new HashSet<Student>();
}
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Student> Students
{
get { return this._students; }
set { this._students = value; }
}
}
I hope that this can help you solve your issue.
I want to create large user table (advance User Profile) and save user's data in my database context. So, I don't want to use 2 DbContexts in my project. When users register to site, they data (UserName, Password etc.) stores my own User table. My classes are like this:
public class ModelBase
{
public int Id { get; set; }
public DateTime CreateDate { get; set; }
public DateTime LastUpdateDate { get; set; }
}
public class User : ModelBase
{
public string UserName { get; set; }
public string Password{ get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public DateTime BirthDate { get; set; }
public string Specialty { get; set; }
}
public class News : ModelBase
{
public int UserId { get; set; }
public string Title { get; set; }
...
}
....
Context is so:
public class MyDBContext : DbContext
{
public MyDBContext()
{
Database.SetInitializer<MyDBContext>(new MyDBContextInitializer());
}
public DbSet<User> UserSet { get; set; }
public DbSet<News> NewsSet { get; set; }
public DbSet<Project> ProjectSet { get; set; }
public DbSet<Section> SectionSet { get; set; }
....
}
class MyDBContextInitializer : DropCreateDatabaseIfModelChanges<MyDBContext>
{
protected override void Seed(MyDBContext context)
{
base.Seed(context);
}
}
I replaced DbContext name with mine and changed connection name in default SimpleMembershipInitializer class like this:
....
Database.SetInitializer<MyDBContext>(null);
try
{
using (var context = new MyDBContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("MyDBContextConnection", "User", "Id", "UserName", autoCreateTables: true);
....
Finally, I changed RegisterModel and WebSecurity.CreateUserAndAccount() suitable my User class. But, it does not work.
How can I use my own User table for register to site?
You can have Asp.net Membership and your complex classes connected together.
with this approach you will save so much time because asp.net membership is much more robust(you don't need to think about Role and User management) and sure you can make use of existing open source project like this and add it to your project with minimum effort of time.
Then your class will have structure like :
public class CustomUserDetail : ModelBase
{
public string UserName { get; set; } // what you really need is this to be unique for each user in you data base
// public string Password{ get; set; } handled by asp.net Membership
public string FullName { get; set; }
// public string Email { get; set; } handled by asp.net Membership
public DateTime BirthDate { get; set; }
public string Specialty { get; set; }
}
Then you can can add extension method to IPrincipal like :
public static CustomUserDetail CustomUserDetail (this IPrincipal principal)
{
var repository = new YourUserDetailRepository();
return repository.GetCurrentUserDetail();
}
and finnaly in your code easily use
<p> #User.CustomUserDetail.FullName </p>
I get this error on this line of code -
ReportRunnerEntities reportDB = new ReportRunnerEntities();
public ActionResult Index()
{
**var types = reportDB.ReportTypes.ToList();**
return View(types);
}
The tables in the databse have primary keys defined and identities set.
My models are -
namespace ReportRunner.Models
{
public partial class ReportRunnerEntities : DbContext
{
public DbSet<Reports> Report { get; set; }
public DbSet<ReportTypes> ReportTypes { get; set; }
public DbSet<Users> Users { get; set; }
}
}
namespace ReportRunner.Models
{
public partial class ReportTypes
{
public int ReportTypeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Reports> Reports { get; set; }
}
}
namespace ReportRunner.Models
{
public class Reports
{
public int ReportId { get; set; }
public int ReportTypeId { get; set; }
public int UserId { get; set; }
public string Title { get; set; }
public ReportTypes ReportType { get; set; }
}
}
namespace ReportRunner.Models
{
public partial class Users
{
public int UserId { get; set; } //ArtistId
public string Name { get; set; }
}
}
and here is my connection string -
I suspect that it's never reaching the database. As I said the keys are set in the database.
Am I missing something?
There are a couple things I see that should change:
ReportTypes should be ReportType
public List Reports { get;
set; } should be public
ICollection Reports { get;
set; }
If you are defining a
connection string in your web.config,
you need to tell EF what one it is
using the constructor in your
ReportRunnerEntities class like this:
namespace ReportRunner.Models
{
public partial class ReportRunnerEntities : DbContext
{
public ReportRunnerEntities : base("name=NameOfConnectionInWebConfig")
{}
public DbSet<Reports> Report { get; set; }
public DbSet<ReportTypes> ReportTypes { get; set; }
public DbSet<Users> Users { get; set; }
}
}
You can read more on that here : http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-2-connections-and-models.aspx
Just on a side note, if you are planning on using .NET MVC and EF Code First as your stack, I would start using the Repository and Unit of Work pattern. Here is a good post on how to set that up: Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable