Many to Many with EF, FluentAPI and Identity - c#

I want to add a many-to-many-relationship to my database using EF 6.
I want to add a many to many between the AppUser and Courses. Here are my models:
AppUser
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
namespace WebApplication2.Models
{
public class AppUser : IdentityUser<Guid>
{
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public IList<AppUserCourse> AppUserCourses { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
Course
namespace WebApplication2.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public IList<AppUserCourse> AppUserCourses { get; set; }
}
}
AppUserCourse (Joined Table)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication2.Models
{
public class AppUserCourse
{
public Guid AppUserId { get; set; }
public AppUser AppUser { get; set; }
public int CourseId { get; set; }
public Course Course { get; set; }
}
}
DataContext.cs
using WebApplication2.Models;
using Microsoft.EntityFrameworkCore;
using System;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace WebApplication2
{
public class DataContext : IdentityDbContext<AppUser, AppRole, Guid>
{
public DataContext(DbContextOptions<DataContext> options) : base(options)
{
}
public DbSet<Course> Courses { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<AppUser> AppUsers { get; set; }
public DbSet<AppUserCourse> AppUserCourses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<AppUserCourse>().HasKey(i => new { i.AppUserId, i.CourseId });
}
}
}
When I know do a migration and update my database, EF is creating my something strange in the AppUserCourses-Table:
It creates my the AppUserId twice (AppUserId and AppuserId1): Former as int and latter as uniqueidentifier.
I would need it just once as unique identifier. When I now try to add a new AppUserCourse, I get the error message:
Operand type clash: uniqueidentifier is incompatible with int.

On your AppUserCourse remove the entities, so it looks like the following, re-create your migrations too
public class AppUserCourse
{
public Guid AppUserId { get; set; }
public int CourseId { get; set; }
}
That will create your many to many link
The following is an example I've set up
public class Player
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public List<PlayerGroup> PlayerGroups { get; set; }
}
public class PlayerGroup
{
public int PlayerId { get; set; }
public int GroupId { get; set; }
}
public class Group
{
public int Id { get; set; }
public string Name { get; set; }
public List<PlayerGroup> PlayerGroups { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PlayerGroup>().HasKey(x => new {x.GroupId, x.PlayerId});
}
Creates the following

Related

How to add a foreign key into a table using one-to-one relationship in ASP.NET Core 6 Web API?

I am new to ASP.NET, how can I make my item table save the categoryID which I get from the category table? As an example I want the item "Apple mobile phone" to have the category ID which refers to category name which is electronics, I hope you got the picture.
Here is model:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace WebApplication1.Models
{
public class itemTable
{
[Key]
public int Id { get; set; }
public string company { get; set; }
public string availability { get; set; }
public decimal price { get; set; }
public decimal discount { get; set; }
public decimal tax { get; set; }
public string description { get; set; }
public int categoryid { get; set; }
}
public class categories
{
[Key]
public int categoryID { get; set; }
public string categoryName { get; set; }
}
}
And here is my DbContext:
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using WebApplication1.Models;
namespace WebApplication1.Context
{
public class itemTableDbContext : DbContext
{
public itemTableDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<itemTable> ItemTables { get; set; }
public DbSet<categories> categories { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<itemTable>().ToTable("itemtable");
modelBuilder.Entity<categories>().ToTable("categories");
}
}
}
I tried all the possible ways but there is always something wrong, multiple items might be in the same category like phone brand items are all under the "electronics" category
You can configure One-to-One relationship between two entities in such way:
public class ItemTable
{
[Key]
public int Id { get; set; }
public string Company { get; set; }
public string Availability { get; set; }
public decimal Price { get; set; }
public decimal Discount { get; set; }
public decimal Tax { get; set; }
public string Description { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
[Key]
[ForeignKey("ItemTable")]
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public virtual ItemTable ItemTable { get; set; }
}
Note: Better to use PascalCase in C#

Identity in C# ASP.NET Core Web API user

I have a project it's about real estate so I created tables user and linked it with estates, and I learnt about identity.
When I migrate it hides the user table because the ASP.NET Core identity already has a users table, so how can I link asp.net user to users or how to link asp.net user to identity user
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Try.DAL.Entity
{
[Table("Users")]
public class Users
{
[Key]
public int Id { get; set; }
[StringLength(50)]
public string Fname { get; set; }
[StringLength(50)]
public string Lname { get; set; }
public string Email { get; set; }
public string Password { get; set; }
[StringLength(20)]
public string Phone { get; set; }
public DateTime Signupdate { get; set; }
public int Usergroupid { get; set; }
[ForeignKey("Usergroupid")]
public UserGroup Usergroup { get; set; }
public virtual ICollection<Estate> Estate { get; set; }
}
}
using Microsoft.EntityFrameworkCore;
using Try.DAL.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Try.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
//using Try.Models;
namespace Try.DAL.Database
{
public class DbContainer : IdentityDbContext
{
public DbContainer(DbContextOptions<DbContainer> opts) : base(opts) { }
public virtual DbSet<RefreshToken> RefreshTokens { get; set; }
public DbSet<Users> Users { get; set; }
public DbSet<Ads> Ads { get; set; }
public DbSet<Clients> Clients { get; set; }
public DbSet<Feedback> Feedback { get; set; }
public DbSet<Interests> Interests { get; set; }
public DbSet<Orders> Orders { get; set; }
public DbSet<Estate> Estate { get; set; }
public DbSet<users> users{ get; set; }
Modify your Dbcontext class as below:
public class UserTestDbContext : IdentityDbContext
{
public UserTestDbContext(DbContextOptions<UserTestDbContext> options)
: base(options)
{
}
public DbSet<_3._7.Models.User> User { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().ToTable("User");
}
}
And I have simpfied the class as below:
public class User:IdentityUser
{
public int Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
}
Result:
The migration class:
and the database:
And if you modify the dbcontext class as follow:
public class UserTestDbContext : IdentityDbContext<User>
{
public UserTestDbContext(DbContextOptions<UserTestDbContext> options)
: base(options)
{
}
public DbSet<_3._7.Models.User> User { get; set; }
}
You could find the properties of user class has been added to the ASPNetUser Table.
You have to add the fields you want to add to the identity users table in the applicationDbContext.cs file like this:
namespace Try.DAL.Database
{
// You add this class here with custom fields.
public class ApplicationUser : IdentityUser
{
// add properties here.
[StringLength(50)]
public string Fname { get; set; }
[StringLength(50)]
public string Lname { get; set; }
public string Email { get; set; }
public string Password { get; set; }
[StringLength(20)]
public string Phone { get; set; }
public DateTime Signupdate { get; set; }
public int Usergroupid { get; set; }
[ForeignKey("Usergroupid")]
public UserGroup Usergroup { get; set; }
public virtual ICollection<Estate> Estate { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Users> Users { get; set; }
public DbSet<Ads> Ads { get; set; }
public DbSet<Clients> Clients { get; set; }
public DbSet<Feedback> Feedback { get; set; }
public DbSet<Interests> Interests { get; set; }
public DbSet<Orders> Orders { get; set; }
public DbSet<Estate> Estate { get; set; }
}
}

Using interfaces with POCO objects?

I am trying to incorporate interfaces in my latest application. With simple classes it seems to be pretty straight forward but with classes with relationships things seem to get weird. What is the correct way to use interfaces with classes with relationship?
My interfaces:
public interface IAgent
{
string FirstName { get; set; }
int Id { get; set; }
string LastName { get; set; }
IEnumerable<ITeam> Teams { get; set; }
}
public interface ITeam
{
string Name { get; set; }
int Id { get; set; }
IEnumerable<IAgent> Agents { get; set; }
}
My classes end up being:
public class Agent : IAgent
{
public Agent()
{
Teams = new HashSet<Team>();
}
public string FirstName { get; set; }
public int Id { get; set; }
public string LastName { get; set; }
public virtual IEnumerable<ITeam> Teams { get; set; }
}
public class Team : ITeam
{
public Team()
{
Agents = new HashSet<Agent>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<IAgent> Agents { get; set; }
}
Structured this way the POCO classes will not create the relationship table using code first migrations.
And my Context Class:
public class SDRContext :DbContext
{
public SDRContext():base("SDRContext")
{
}
public DbSet<Agent> Agents { get; set; }
public DbSet<Team> Teams { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("SDR");
base.OnModelCreating(modelBuilder);
}
}

EF Code first not creating table with npgsql

I am using EF code first with Npgsql. Everything is fine till i try to save changes using contextclassObj
public class EmployeeRepository
{
private ESAppraisalcontext DBAccessObj = null;
public EmployeeRepository()
{
DBAccessObj = new ESAppraisalcontext();
DBAccessObj.Employees.Add(new Employee { EmployeeCode = "1", EmployeeName = "shuk" });
DBAccessObj.SaveChanges();
}
}
At the point SaveChanges() it gives an exception that the Relation \ ESTables.Employee\ doesnot exist.Here is my context class :
public class ESAppraisalcontext : DbContext
{
public DbSet<Entity> Entities { get; set; }
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("ESTables");
base.OnModelCreating(modelBuilder);
}
}
And my model:
public class Employee
{
[Key]
public string EmployeeCode { get; set; }
public string EmployeeName { get; set; }
public string EmailId { get; set; }
public string DomainName { get; set; }
public int DesignationId { get; set; }
public int DepartmentId { get; set; }
public string MgrCode { get; set; }
public int LocationId { get; set; }
public DateTime DOJ { get; set; }
public bool IsActive { get; set; }
public bool IsEligibleForCycle { get; set; }
public bool IsNonEligibleApprover { get; set; }
[ForeignKey("DepartmentId")]
public Departments department { get; set; }
[ForeignKey("DesignationId")]
public Designations designation { get; set; }
[ForeignKey("LocationId")]
public Locations Loation { get; set; }
}

Code First Migration: Two foreign keys referencing on the same table in Entity Framework Core

I have the following Models in ASP.NET(Core 1.0) MVC Framework. I am using Entity Framework Core. I want to create a table "Deliveries" with two foreign keys from the same table Addresses(a pick-up address and a drop-off address). My implementation is wrong so I would like to ask you if you know:
how to declare those properties
how to set onupdate and ondelete actions for those keys?
ApplicationDbContext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using JBCoreApp.Models;
using Microsoft.EntityFrameworkCore.Metadata;
namespace JBCoreApp.Data
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Country> Countries { get; set; }
public DbSet<AddressType> AddressTypes { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<Profile> Profiles { get; set; }
public DbSet<VehicleType> VehicleTypes { get; set; }
public DbSet<LicenseCategory> LicenseCategories { get; set; }
public DbSet<Driver> Drivers { get; set; }
public DbSet<DriverLicense> DriverLicenses { get; set; }
public DbSet<Priority> Priorities { get; set; }
public DbSet<Sender> Senders { get; set; }
public DbSet<Status> Statuses { get; set; }
public DbSet<Vehicle> Vehicles { get; set; }
public DbSet<Delivery> Deliveries { get; set; }
public DbSet<DeliveryStatus> DeliveryStatus { get; set; }
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);
builder.Entity<Delivery>()
.HasOne(a => a.DropOffAddress)
.WithOne()
.HasForeignKey<Address>(a => a.Id)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity<Delivery>()
.HasOne(a => a.PickUpAddress)
.WithOne()
.HasForeignKey<Address>(a=> a.Id)
.OnDelete(DeleteBehavior.Restrict);
}
}
}
Address.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace JBCoreApp.Models
{
[Table("Addresses")]
public class Address
{
public Address()
{
}
[Key]
public int Id { get; set; }
public int ProfileId { get; set; }
public Profile Profile { get; set; }
public int TypeId { get; set; }
[ForeignKey("TypeId")]
public AddressType AddressType { get; set; }
public string Street { get; set; }
public string StreetNumber { get; set; }
public string PostCode { get; set; }
public string City { get; set; }
public string CountryId { get; set; }
public Country Country { get; set; }
public string Notes { get; set; }
}
}
Delivery.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace JBCoreApp.Models
{
[Table("Deliveries")]
public class Delivery
{
public Delivery()
{
}
[Key]
public int Id { get; set; }
[Required]
public int SenderId { get; set; }
public Sender Sender { get; set; }
[Required]
public int VehicleTypeId { get; set; }
public VehicleType VehicleType { get; set; }
[Required]
public int PriorityId { get; set; }
public Priority Priority { get; set; }
public int DriverId { get; set; }
public Driver Driver { get; set; }
[ForeignKey("PickUpAddressId")]
public Address PickUpAddress { get; set; }
public int PickUpAddressId { get; set; }
[ForeignKey("DropOffAddressId")]
public Address DropOffAddress { get; set; }
public int DropOffAddressId { get; set; }
public DateTime PickUpDateTime { get; set; }
public DateTime DropOffDateTime { get; set; }
public DateTime Deadline { get; set; }
public string Description { get; set; }
public string Price { get; set; }
[Timestamp]
public Byte[] TimeStamp { get; set; }
}
}

Categories