I have 3 tables
User > Employee > Operator
There is a one to one relation on each other's end
public class User
{
[Key]
public int Id { get; set; }
public string Username { get; set; }
public DateTime? LoginDate { get; set; }
public bool IsActive{ get; set; }
public ICollection<Role> Roles { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee
{
[Key]
[ForeignKey("User")]
public int Id { get; set; }
public string Name{ get; set; }
public string Email { get; set; }
public int UserId { get;set; }
public virtual User User { get; set; }
public virtual Operator Operator{ get; set; }
}
public class Operator
{
[Key]
[ForeignKey("Employee")]
public int Id { get; set; }
public int EmployeeId {get;set;}
public EmployeeEmployee{ get; set; }
}
However this does create the one to one relation when i create a diagram in Sql Server MS to check the relations.
Problem is, when I'm just trying to insert data directly graphically from Sql it expects me to insert the primary key on Employee and Operator tables. Why aren't they automatic like the User one?
First, you don't need specify two variables to store same informations.
public int UserId { get;set; }
public int EmployeeId {get;set;}
already stored in Id. Not need to duplicate it.
Foreign keys doesn't use identity (doesn't generate values). So you need create User and then create an Employe where set the "User" property with user created before. (Main idea is that you need initialise reference to foreign key manually)
User user = new User{...};
Employee employe = new Employee{User = user, ...};
context.Add(employee);
context.SaveChanges();
Or maybe you will use hierarchy. (I don`t checked on 3 level, but on 2 this works perfectly).
public class User
{
[Key]
public int Id { get; set; }
public string Username { get; set; }
public DateTime? LoginDate { get; set; }
public bool IsActive{ get; set; }
public ICollection<Role> Roles { get; set; }
}
public class Employee : User
{
public string Name{ get; set; }
public string Email { get; set; }
}
public class Operator : Employee
{
}
Related
Say I want to model a relationship between users and auctions. A user can host an auction in which other users can bid in, while he can also bid in auctions of other users. So I want a User table, an Auction table with a foreign key reference to the User table, and an AuctionBidders table.
What do I have to add/change in the code below or in the OnModelCreating() method to make it work?
public class User
{
public int Id { get; set; }
public ICollection<Auction> Auctions { get; set; }
}
public class Auction
{
public int Id { get; set; }
public User Host { get; set; }
public ICollection<User> Bidders { get; set; }
}
Assuming that one action can have only have one Host, but the same user can be a Host for many auctions, you have to add relations for Host too
public class User
{
public int Id { get; set; }
[InverseProperty(nameof(Auction.Host))]
public ICollection<Auction> Hosts { get; set; }
public ICollection<Auction> Auctions { get; set; }
}
public class Auction
{
public int Id { get; set; }
public int HostId { get; set; }
[ForeignKey(nameof(HostId))]
[InverseProperty(nameof(User.Hosts))]
public User Host { get; set; }
public ICollection<User> Users { get; set; }
}
ef core 5+ will create the third table for you but I would prefer to add it explicetely since you have non standard db structrure
public class AuctionUser
{
[Key]
public int Id { get; set; }
public int AuctionId { get; set; }
[ForeignKey(nameof(AuctionId))]
[InverseProperty("Users")]
public virtual Auction Auction { get; set; }
public int UserId { get; set; }
[ForeignKey(nameof(UserId))]
[InverseProperty("Auctions")]
public virtual User User { get; set; }
}
I'm basically trying to enforce this in Entity Framework: Require Only One Of Multiple Columns Be Not Null
My database has several 1:m relationships where the child entity belongs to one of several parent entities. For example, let's say I have tables for Teachers, Students, and Guardians. Each of those can have many PhoneNumbers and EmailAddresses. I am using EF Code First, and my models look something like:
public class Teacher {
public int Id { get; set; }
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
}
public class Student {
public int Id { get; set; }
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
}
public class Guardian {
public int Id { get; set; }
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
}
public class PhoneNumber {
public int Id { get; set; }
public string Number { get; set; }
}
public class EmailAddress {
public int Id { get; set; }
public string Email { get; set; }
}
When I run the migration, this creates the database with the tables/columns I would expect. The PhoneNumbers and EmailAddresses tables each have columns Teacher_Id, Student_Id, and Guardian_Id, which are foreign keys to their respective parent entity. However, there are no constraints on how many parent entities can be set on the child. For example, I can create a PhoneNumber that has all three parent IDs set to null, or I can set both a Teacher_Id and a Guardian_Id.
I tried adding a required attribute to the parents like so:
public class Teacher { // Also Student/Guardian
public int Id { get; set; }
public string Name { get; set; }
[Required]
public List<PhoneNumber> PhoneNumbers { get; set; }
[Required]
public List<EmailAddress> EmailAddresses { get; set; }
}
That does not seem to have any effect.
I think there is no way to do this on entities. Instead, create a migration and try to alter the table in migration class like this:
public partial class YourMigrationName: Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("ALTER TABLE [dbo].[PhoneNumber]
WITH CHECK ADD CONSTRAINT [CK_PhoneNumer_Teacher_Student_Guardian] CHECK (Teacher_Id
is not null or Student_Id is not null or Guardian_Id is not null)
GO
ALTER TABLE [dbo].[EmailAddress] WITH CHECK ADD CONSTRAINT
[CK_EmailAddress_Teacher_Student_Guardian] CHECK (Teacher_Id is not null or
Student_Id is not null or Guardian_Id is not null)
");
}
}
Try this:
public class PhoneNumber
{
public int Id { get; set; }
public string Number { get; set; }
//Added this code:
[Required]
public Teacher Teacher { get; set;}
}
public class EmailAddress {
public int Id { get; set; }
public string Email { get; set; }
//Added this code:
[Required]
public Teacher Teacher { get; set;}
}
That would make sure you cannot create PhoneNumber without Teacher. You can also do this:
public class PhoneNumber
{
public int Id { get; set; }
public string Number { get; set; }
public int TeacherId
public Teacher Teacher { get; set;}
}
That would also detect that you want to add constraint on your PhoneNumber. Both ways work fine.
I am new to Entity Framework. I am using database first approach and I don't auto generate entity files. I have 3 tables User, Database and UserDatabase. The table UserDatabase has a many-to-many relationship with both User and Database. I am not sure how to build this relationship in my class.
public class Database
{
[Key]
public int DatabaseId { get; set; }
public string DatabaseName { get; set; }
}
public class User
{
[Key]
public int? UserID { get; set; }
[Required]
public string Name{ get; set; }
}
public class UserDatabase
{
[Key]
public int UserID { get; set; }
[ForeignKey("UserID")]
public virtual User Users{ get; set; }
public int DatabaseID { get; set; }
[ForeignKey("DatabaseID")]
public virtual Database Database { get; set; }
}
This is my current code. If I add one database per user it is working fine. But if I add multiple, it throws multiplicity constraint violation error. Please help.
I have found out the mistake. In the link table "UserDatabase" I have mentioned UserID as the primary key and that is why I am not able to add multiple records. It should be a composite key and I have marked both user and database as key and given the order. I have changed it to
public class UserDatabase
{
[Key, Column(Order=0)]
public int UserID { get; set; }
[ForeignKey("UserID")]
public virtual User Users{ get; set; }
[Key, Column(Order=1)]
public int DatabaseID { get; set; }
[ForeignKey("DatabaseID")]
public virtual Database Database { get; set; }
}
Try modifying your UserDatabase to following:
public class UserDatabase
{
[ForeignKey("Users")]
public int UserID { get; set; }
[ForeignKey("Database")]
public int DatabaseID { get; set; }
public virtual User Users{ get; set; }
public virtual Database Database { get; set; }
}
I am trying to create my first app using ASP.NET MVC framework and Entity Framework 6.
I chose to use code first approach and I started by defining my Models.
I have a model called Client with an identity attribute called Id. I have multiple Models that has an attribute called ClientId. The ClientId attribute should have virtual link to the Clients Model.
Here is how my Client model looks like
[Table("clients")]
public class Client
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string status { get; set; }
public DateTime created_at { get; set; }
public DateTime? modified_at { get; set; }
public Client()
{
status = "Active";
created_at = DateTime.UtcNow;
}
}
Then here is how I am creating a belong to relation using other models.
[Table("BaseClientsToUsers")]
public class ClientToUser : ModelDefault
{
[ForeignKey("User")]
public int UserID { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
[ForeignKey("Team")]
public int DefaultTeamId { get; set; }
public DateTime? JoinedAt { get; set; }
public bool IsActive { get; set; }
public virtual User User { get; set; }
public virtual Client Client { get; set; }
public virtual Team Team { get; set; }
public ClientToUser()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
[Table("BaseTeams")]
public class Team : ModelDefault
{
[MaxLength(250)]
public string Name { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
public bool IsActive { get; set; }
public virtual Client Client { get; set; }
public Team()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
}
But, when I try to update my databases I get the following error
Introducing FOREIGN KEY constraint
'FK_dbo.BaseTeams_dbo.BaseClients_ClientId' on table 'BaseTeams' may
cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or
ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could
not create constraint or index. See previous errors.
I am not really sure what could be causing the error but it seems it is because I am creating multiple Foreign keys to the same `Clients model.
How can I fix this error?
Hello #Mike A When I started MVC I got this error too, so you need aditional tables that connects your DB items.
So try connect your database items with tables like that:
Here is my working example:
[Table("Products")]
public class Product
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal InternalPrice { get; set; }
public string Url { get; set; }
}
[Table("Categories")]
public class Category
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Url { get; set; }
}
[Table("ProductCategories")]
public class ProductCategory
{
[Key]
[Column(Order = 0)]
public string ProductId { get; set; }
[Key]
[Column(Order = 1)]
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
So you can connect your items without problems hope this will help you.
I want to set the relationship of some tables and make some columns in the table can be null.
[Table("tbl_useraccount")]
public class AccountViewModels
{
[Key]
public string AccountId { get; set; }
public string Email { get; set; }
public string HashPassword { get; set; }
}
and here is the table which I want to make relationship:
[Table("tbl_userprofile")]
public class UserProfileViewModels
{
[Key]
public int Id { get; set; }
public string AccountId { get; set; }
public string Address { get; set; }
public int PhoneNumber { get; set; }
}
My question is: How to set AccountId (in the table tbl_useraccount) is the primary key and as the foreign key in the table tbl_userprofile from Model?
And my sub-question is: Is it necessary to set NULL or NOT NULL for per column name? If it is necessary, how can I do that?
p/s: I'm using MVC 5 and SQL Server.
First remark I have is that you don't use viewmodels for your database generation. ViewModels are only used for your views.
To create a relationship, you should add the AccountModel to the UserProfile, I added virtual to enable lazy loading. Also add the ForeignKey data annotation to the extra property you want to map your key to (optional)
[Table("tbl_useraccount")]
public class AccountModel
{
[Key]
public string AccountId { get; set; }
public string Email { get; set; }
public string HashPassword { get; set; }
}
[Table("tbl_userprofile")]
public class UserProfileModels
{
[Key]
public int Id { get; set; }
public string AccountId { get; set; }
public string Address { get; set; }
[ForeignKey("AccountModel")]
public int PhoneNumber { get; set; }
public virtual AccountModel AccountModel { get; set;}
}
If you want a field not to be null, if this is even possible. Use the [Required] data annotation. "Public int PhoneNumber" can not be null, you'll have to write it as following: "Public int? PhoneNumber".