How to add a new table with EF core - c#

I have an existing database already that was created when i added Identity to the project. Now i wanna add more tables to the database and can't figure out how.
I have created a model for it:
public class Match
{
public Guid ID { get; set; }
public string HomeTeam { get; set; }
public string AwayTeam { get; set; }
public int FullTimeScore { get; set; }
public DateTime MatchStart { get; set; }
public int PrizePool { get; set; }
}
My context:
public class DynamicBettingUserContext : IdentityDbContext<IdentityUser>
{
public DynamicBettingUserContext(DbContextOptions<DynamicBettingUserContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
What's the next steps?

You need to add the Match table in your DynamicBettingUserContext class like below. Then You need to add migration using Add-Migration <YourMigrationName> in Package Manager Console and finally, You have to run Update-Database command in PMC.
public virtual DbSet<Match> Match { get; set; }

Related

EF Core Many to Many with Identity User not working

So if I understand correctly, EF Core 5.0 updated how to make your many to many relationship. I wanted to try this out using IdentityUser & Tournament classes. Here is the code that I have.
Tournament Class:
public class Tournament
{
public int Id { get; set; }
public string Title { get; set; }
public ICollection<AppUser> Participants { get; set; }
}
IdentityUser Class
(I have tried to set the id as int too)
public class AppUser : IdentityUser
{
public ICollection<Tournament> RegisteredTournaments;
}
In my Startup class:
services.AddIdentity<AppUser, IdentityRole>()
.AddEntityFrameworkStores<DataContext>();
And lastly, my DbContext class (AppUsers out of comments changes nothing)
public class DataContext : IdentityDbContext<AppUser>
{
//public DbSet<AppUser> AppUsers { get; set; }
public DbSet<Tournament> Tournaments { get; set; }
public DataContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
But now, when I add this migration, it will only add a FK 'TournamentId' into the AspNetUsers table. Anything I can do to properly implement this?
Thanks in advance,
Janne

ASP.NET Identity relationship

I have a question.
I'm using ASP.NET CORE Identity(Individual User Accounts). It's already creating a separate database independent of my project. In my project, there are things I need to list that belong to the user. How can I do this ?
Database1-> ASP.NET CORE Identity Database (this database was created automatically)
Database2-> My App database
In Database2 Example Code;
public class Report:BaseModel
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime DateTime { get; set; }
public int UserId { get; set; } //(IT MUST BE ASP.NET USER TABLE)
public User User { get; set; } //(IT MUST BE ASP.NET USER TABLE)
}
First make sure that you have OnModelCreating on your DbContext class with base call
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
then add your class
public class Report : BaseModel
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime DateTime { get; set; }
public ApplicationUser User { get; set; }
}
then call migrations add-migration Report and Update-Database

Duplicate table created when adding IdentityUser as foreign key in ASP.NET Core 3.1

I am using PostgreSql as my DB. I am trying to add a foreign key to the user's table but instead of that a duplicate IdentityUser table is being created.
I have inherited IdentityDbContext<IdentityUser> for ApplicationDbContext whose code is:
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
This is able to create all the tables as:
I am trying to create a model where the user is the foreign key by doing:
public class AccountModel
{
[Key]
public string Id { get; set; } = Guid.NewGuid().ToString();
public string AccountName { get; set; }
public string AccountNumber { get; set; }
public BankModel BankDetails { get; set; }
public IdentityUser User { get; set; }
}
And it's DBContext is
public class AccountDbContext: DbContext
{
public AccountDbContext(DbContextOptions<AccountDbContext> options) : base(options)
{
}
public DbSet<AccountModel> Accounts { get; set; }
public DbSet<BankModel> Banks { get; set; }
}
Looking at the post - https://stackoverflow.com/a/41275590/3782963, the accepted answer uses ApplicationUser which I believe is similar to IdentityUser, when I do the migrations, instead of adding an FK to AspNetUsers it creates a new table called IdentityUser and then an FK is added to this newly created table. Which looks like:
I am not sure what I am doing wrong. Help!
Update
I tried this code with Azure SQL Server too and it still gave me the same problem. Also, I added [ForeignKey("AspNetUser")]
public class AccountModel
{
[Key]
public string Id { get; set; } = Guid.NewGuid().ToString();
public string AccountName { get; set; }
public string AccountNumber { get; set; }
public BankModel BankDetails { get; set; }
[ForeignKey("AspNetUsers")]
public IdentityUser User { get; set; }
}
I still get the same problem.
Update 2
The relationship is between two different contexts, i.e. ApplicationDbContext and AccountDbContext. Adding public DbSet<AccountModel> Accounts { get; set; } to ApplicationDbContext works fine and automatically adds an FK relationship.
You need to define the relationship between AccountModel and IdentityUser in your model builder.
Something along the lines of
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<AccountModel>()
.HasOne(accountModel=> accountModel.User);
base.OnModelCreating(builder);
}
See here for info on single navigation property and foreign keys.

.Net Core API with EF Core Code First and IdentityUser

I have an existing application that I am re-writing as .NET Core API with a ReactJS front-end. I am still in the API end, and I've run into a problem.
CODE
I have a BbUser.cs entity class with the following code:
public class BbUser : IdentityUser
{
public int Points { get; set; } = 0;
public string DisplayUsername { get; set; }
}
And I also have an Artist.cs entity class:
public class Artist
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[MaxLength(50)]
public string LastName { get; set; }
[MaxLength(100)]
public string UrlFriendly { get; set; }
public string ImageUrl { get; set; }
public bool IsVerified { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public ICollection<Lyric> Lyrics { get; set; } = new List<Lyric>();
public string UserId { get; set; }
public BbUser User { get; set; }
}
I need a one-to-many relationship between BbUser and Artist. One user can submit many artists and lyrics ...etc. Simple stuff really.
PROBLEM
The application builds fine, but when I attempt to run it by hitting a controller that requires access to the Database, I get the following error:
The entity type 'IdentityUserLogin' requires a primary key to be defined.
I had this issues with regular EF Code First (not Core) and the fix for that, does not work here.
This model worked for me(compiled, and no exceptions at runtime) if I used next code in the DbContext class:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<BbUser>(b => b.ToTable("AspNetUsers"));
base.OnModelCreating(builder);
}
Without calling base.OnModelCreating(builder) I get the same error, because in this case context isn't applying the Identity related schema.
UPDATE:
Everything works fine for me as you can see from the screenshot below:
I have one more idea why you can have such an error. Did your BbContext inherit from DbContext class or IdentityDbContext<IdentityUser>? Because I got the same error that was on your screenshot if I used usual DbContext class.
In order to Idenity tables work fine you should use IdentityDbContext<IdentityUser>. Below the whole code for my working DbContext class
public class BbContext :IdentityDbContext<IdentityUser>
{
public BbContext(DbContextOptions options):base(options)
{
Database.EnsureCreated();
}
public DbSet<Artist> Artists { get; set; }
public DbSet<Lyric> Lyrics { get; set; }
public DbSet<Heart> Hearts { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<BbUser>(b => b.ToTable("AspNetUsers"));
builder.Entity<Heart>().HasKey(h => new {h.UserId, h.LyricId});
base.OnModelCreating(builder);
}
}
Please do try declaring a Guid property named Id, with both Get and Set on the IdentityUserLogin entity.
Another option is to declare a property and decorate it with [Key] attribute

How to Specify Entity Framework Core Table Mapping?

I've made a simple Entity Framework ASP Core Application that works but I do not know why:
I've made a context like this:
public class AstootContext : DbContext
{
public AstootContext(DbContextOptions<AstootContext> options)
: base(options)
{ }
public DbSet<Account> Accounts { get; set; }
public DbSet<User> Users { get; set; }
}
And I have two tables with models like this:
public class Account
{
public int Id { get; set; }
public string Username { get; set; }
public string PasswordHash { get; set; }
public DateTime Created { get; set; }
List<User> Users { get; set; }
}
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public DateTime Birthday { get; set; }
public Account Account { get; set; }
}
The interesting thing is that when I run my application it actually can pick up the data. It just seems weird because I have not specified any table mapping.
I'm assuming this just automaps because the specified tables are the same name.
My questions are:
How do I specify Table explicit table mapping in case I do not want my model names to be exactly the same as the DB?
How do I specify Custom Column Mapping.
Is there anything special I have to specify for Primary/Foreign Keys
edit
To clarify
Say I had a table in the DB MyAccounts and I wanted to map that to an entity Accounts.
Say I had a column password and I wanted that to map to a POCO property PasswordHash
To specify the name of the database table, you can use an attribute or the fluent API:
Using Attributes:
[Table("MyAccountsTable")]
public class Account
{
public string PasswordHash { get; set; }
}
Using Fluent API:
public class YourContext : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Language>(entity => {
entity.ToTable("MyAccountsTable");
});
}
}
To name your columns manually, it's very similar and you can use an attribute or the fluent API:
Using Attributes:
public class Account
{
[Column("MyPasswordHashColumn")]
public string PasswordHash { get; set; }
}
Using Fluent API:
public class YourContext : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Language>(x => x
.ToTable("MyAccountsTable")
.Property(entity => entity.PasswordHash)
.HasColumnName("MyPasswordHashColumn")
);
}
}

Categories