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; }
}
Related
I have some problems to correctly use Entity Framework with one to many relationships.
here is a part of the model :
public class User
{
[Required]
public int UserID { get; set; }
[Required]
public string Login { get; set; }
//one to many relationship
public virtual Group Group { get; set; }
}
public class Group
[Required]
public int GroupID { get; set; }
[Required]
public string Name { get; set; }
public virtual Group ParentGroup { get; set; }
public virtual List<Group> ChildGroups { get; set; }
[Required]
public User CreatedBy { get; set; }
}
public class OtherClass
[Required]
public int OtherClassID { get; set; }
[Required]
public User CreatedBy { get; set; }
}
I have a question about the update an OtherClass entity.
When I get an entity to update, it doesn't have dependencies loaded, I have to add them with an Include like this :
using (var db = new DalContext())
{
var test = db.OtherClasses.Include(o => o.CreatedBy).Single....
}
But if I want to update an OtherClass entity, why all dependencies have to be loaded?
To resume, when I want to update an OtherClass entity, CreatedBy dependency must be completely loaded, with the group, and for the group, the parent group and child groups, with users...
Is there a possibility to add or update an entity with only ID attributes filled?
Thank you for your help.
I'm not an expert, but here is what I would try:
I believe you should have a UserId in your Group and OtherClass classes, like this:
public class User
{
[Required]
public int UserID { get; set; }
[Required]
public string Login { get; set; }
//one to many relationship
public virtual Group Group { get; set; }
}
public class Group
[Required]
public int GroupID { get; set; }
[Required]
public string Name { get; set; }
public virtual Group ParentGroup { get; set; }
public virtual List<Group> ChildGroups { get; set; }
[Required]
public int UserId { get; set; }
//If you want to lazy-load the user when you load the Group entity, use virtual
//Then you don't need the .Include(g=>g.User)
public virtual User CreatedBy { get; set; }
}
public class OtherClass
[Required]
public int OtherClassID { get; set; }
[Required]
public int UserId { get; set; }
public virtual User CreatedBy { get; set; }
}
To update the OtherClass, you update/set the Id properties, not the User property.
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
{
}
I have an Offer entity that provides a link between two users in my system.
public class Offer
{
public OfferStatus Status { get; set; }
public decimal Amount {get; set; }
public virtual User Provider { get; set; }
public virtual User Receiver { get; set; }
}
This User entity has primary key of:
public string Id { get; set; }
I would like to have the two users ID strings appear in the Offer table like so:
public class Offer
{
public OfferStatus Status { get; set; }
public decimal Amount {get; set; }
public string ProviderId { get; set; }
public string ReceiverId { get; set; }
public virtual User Provider { get; set; }
public virtual User Receiver { get; set; }
}
I have tried:
public class Offer
{
public OfferStatus Status { get; set; }
public decimal Amount {get; set; }
public string ProviderId { get; set; }
public string ReceiverId { get; set; }
[ForeignKey(nameof(ProviderId))]
public virtual User Provider { get; set; }
[ForeignKey(nameof(ReceiverId))]
public virtual User Receiver { get; set; }
}
This is how I usually set foreign keys but usually I only have one of them and I use the naming convention magic that EF provides so I know what I have done here is wrong but I am confused how I am supposed to set their foreign key properties.
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 would try to make a relation between two entities : A goup (with an owner and users) and user (which belongs to a unique group). Code :
public class User
{
public int Id { get; set; }
public int GroupId { get; set; }
public virtual Group group { get; set; }
}
public class Group
{
public int Id { get; set; }
public User Owner { get; set; }
public virtual ICollection<User> Users { get; set; }
}
I don't arrive with data annotation to make it corectly.
Thank you so much for your propositions
A solution that works for me :
public class User
{
public int Id { get; set; }
public int? GroupId { get; set; }
[InverseProperty("Users")]
public virtual Group group { get; set; }
}
public class Group
{
public int Id { get; set; }
public int? OwnerId { get; set; }
public User Owner { get; set; }
public virtual ICollection<User> Users { get; set; }
}