I am having a problem in Entity Framework. Entity Framework is generating auto column in sql-server and I am not geting how to make insert operation in that particuler column.
For Example in Teacher class,
public class Teacher
{
[Key]
public String Email { set; get; }
public String Name { set; get; }
public List<TeacherBasicInformation> Teacher_Basic_Information { set; get; } = new List<TeacherBasicInformation>();
public String Password { set; get; }
public List<Course> course { set; get; } = new List<Course>();
[JsonIgnore]
public String JWT_Token { set; get; }
[NotMapped]
[Compare("Password")]
public String ConfrimPassword { set; get; }
}
And in TeacherBasicInformation class ,
public class TeacherBasicInformation
{
[Key]
public int ID { set; get; }
[Required]
[MaxLength(20)]
public String Phone { set; get; }
[Required]
[MaxLength(100)]
public String Address { set; get; }
}
After the migration in the sql server, in TeacherBasicInformation table a auto column is created named 'TeacherEmail'. How Can I insert data into this column using form in asp.net core.
In order to prevent auto-generated columns for FK, use [ForeignKey("YourForeignKey")] on the related table in the entity class:
public int TeacherId { get; set; }
[ForeignKey("TeacherId")]
public virtual Teacher Teacher { get; set; }
It looks like you have the email column set up as the primary key column in your Teacher class, and the related database column. If that's the case, you're going to have trouble with it as it will need to be unique to that record, and primary keys aren't designed to be changed. It can be done in certain scenarios but isn't a best practice.
Perhaps a better approach is to have the [Key] attribute on a property of public int Id { get; set; } so they primary key is now a discrete number instead of an email address. Then you can access, set, and update the email address on each record, without interfering with the key at all.
Related
I have a model class:
public class UserProfile
{
public string UserID { get; set; }
public string Name{ get; set; }
public ICollection<AddressMaster> AddressMaster { get; set; }
}
The above class have a 1 to many relationship with AddressMaster model class given below:
public class AddressMaster
{
public string AddrID{ get; set; }
public string AddressLine1{ get; set; }
public UserProfile UserProfile { get; set; }
public TheatreLocation TheatreLocation { get; set; }
}
The problem is, there is one other model also that has a 1 to many relationship with addressmaster, which is:
public class TheatreLocation
{
public string LocationID { get; set; }
public string Name{ get; set; }
public ICollection<AddressMaster> AddressMaster { get; set; }
}
So instead of having foreign key at the addressmaster, how can we have a intermediate table between addressmaster and the userprofile & another such table b/w addressmaster and theatre?
Or am i getting the whole concept wrong?
Thanks.
So instead of having foreign key at the addressmaster, how can we have
a intermediate table between addressmaster and the userprofile &
another such table b/w addressmaster and theatre?
If you do not want to set any foreign key and add a intermediate table.Design like below:
public class UserProfile
{
[Key]
public string UserID { get; set; }
public string Name { get; set; }
}
public class AddressMaster
{
[Key]
public string AddrID { get; set; }
public string AddressLine1 { get; set; }
}
public class UserAddress
{
[Key]
public string AddrID { get; set; }
public string UserID { get; set; }
}
Add the primary key to the intermediate table UserAddress.The AddrId could only has one value,but the UserID could have many value which is like one-to-many relationship.
Or am i getting the whole concept wrong?
Nothing wrong.Using navigation property like what you did is also good.
Your table definitions would probably wind up something like this:
UserProfile
UserId PK
Theather
TheatreId PK
Address
AddrID PK
AddressLine1
UserAddress
UserId PK & FK
AddressId FK
TheatreAddress
TheatreID PK & FK
AddressId FK
This is just good normalisation - i.e. you have a generic 'address' table in the database. Several entities may have an address and have either one-many or many-many relationships with addresses, but a specific address only needs to be recorded once.
The PK on the intermediate table only on the UserId (for example) ensures that this is one-many and not many-many.
Now I am building a mini blog. when user create a post I want to insert user id from AspNetUsers in post table as a foreign key
here the post model, so can anyone tell me the steps to make it.
public class Post
{
[Required]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Content { get; set; }
[Required]
public string Path { get; set; }
[Required]
public DateTime PostDate { get; set; }
public ApplicationUser User { get; set; }
public IEnumerable<Comment> Comments { get; set; }
}
You have to use the below code to use AspNetUsersId as a foreign key. You can use [Required] if you don't want to make AspNetUsersId as nullable.
public AspNetUsers User { get; set; }
[ForeignKey("AspNetUsersId")]
[Required]
public int AspNetUsersId { get; set; }
Yes, you have to manually set the AspNetUsersId when you are inserting the record in Post table.
Lets say you have object of class Post as obj. So you have to write the below code in your method, if AspNetUsers table PK is Id.
obj.AspNetUsersId = AspNetUsers.Id;
I have an annoying problem that i can't seem to solve. Lets say i have a database with two tables.
Student
INT Id
NVARCHAR(30) Name
INT PrimaryTeacherId
INT SecondaryTeacherId
Teacher
INT Id
NVARCHAR(30) Name
Now when i set foreign key for PrimaryTeacherId and SecondaryTeacherId and use DatabaseFirst mapping in my project i get something like this for Student table
public partial class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int PrimaryTeacherId { get; set; }
public int SecondaryTeacherId { get; set; }
public virtual Teacher Teacher { get; set; }
public virtual Teacher Teacher1 { get; set; }
}
Note the virtual part of the class and their names, Teacher and Teacher1. No matter how i call my FKs entity framework will just override it and set increment names. That's ok if i have one or two keys to the same table but when there is more it's easy to get lost and code looks kinda annoying having object names with numbers in them. I know i can change generated classes name in my solution but when i update model changes will be lost. I'm also using Metadata partial classes for generated classes (mostly for validation and display attributes), can i change name there maybe?
TLDR: I would like to have Teacher and Teacher1 have custom names, so something like this would be awesome
public partial class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int PrimaryTeacherId { get; set; }
public int SecondaryTeacherId { get; set; }
public virtual Teacher PrimaryTeacher { get; set; }
public virtual Teacher SecondaryTeacher { get; set; }
}
I have the following model set up:
public class User
{
[Key]
[Required]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(50)]
public string UserName { get; set; }
[Required]
public TypeOfProfile ProfileType { get; set; }
[StringLength(50)]
public string ProfileName { get; set; }
I don't want to use TPT. I want the user table to be the short summary table for quick loading. Once clicking on a User his profile is fetched. I have multiple types of profiles. E.g
public class Person | Business | Artist
{
[Key]
[Required]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public int UserId { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
public int AddressId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
public virtual Address Address { get; set; }
public virtual IList<Deal> Deals { get; set; }
public virtual IList<Event> Events { get; set; }
public virtual IList<Vacancy> Vacancies { get; set; }
This way I can create a profile for a certain user and give it the same Id as the User Id, hence the DatabaseGeneratedOption.None. This all works fine. But then the collections come into place: Deals, Events, Vacancies,..
public class Event
{
[Key]
[Required]
[Column(Order = 0)]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[Column(Order = 1)]
public int UserId { get; set; }
[Required]
public int AddressId { get; set; }
...
public virtual User User { get; set; }
public virtual Address Address { get; set; }
All is created just fine with Code First except for one thing. In the Events, Deals and Vacancies table a foreign key is created for each type on top of the UserId property of Event, Deal and Vacancy.
Due to this, the model insists on having a profile of each type for the User, while I only want 1 type of profile per user:
Column:
Id (PK, int, not null)
UserId (FK, int, not null)
Keys:
PK_dbo.Events
FK_dbo.Events.dbo.Artists_UserId
FK_dbo.Events.dbo.Businesses_UserId
FK_dbo.Events.dbo.People_UserId
FK_dbo.Events.dbo.Users_UserId
...
I only want the foreign key to the Users_Id to be created. When I delete the other fk's to people, businesses and artists, then everything is working as i want it. Like this:
Column:
Id (PK, int, not null)
UserId (FK, int, not null)
Keys:
PK_dbo.Events
FK_dbo.Events.dbo.Users_UserId
...
But how can I configure code first or by fluent API that the 3 extra foreign keys are not created. (due to the ILists of those Profiles) I don't want to be able to retrieve a profile from the event object, only the User object.
Thanks in advance!
Kr
I solved my problem using a TPH architecture. (Table Per Hierarchy) Now I have only one Profile table with a discriminator for Person, Business and Artist. The primary key of my Profile table is at the same time the foreign key to my User table.
Kr
I recently came across this strange problem with Entity Framework Code First.
My class looks like this
public class Status
{
[Key]
public int StatusID { get; set; }
public string Name { get; set; }
public int MemberID { get; set; }
[ForeignKey("MemberID")]
public virtual Member Member { get; set; }
public int PosterID { get; set; }
[ForeignKey("PosterID")]
public virtual Member Poster { get; set; }
public virtual ICollection<StatusLike> StatusLikes { get; set; }
public virtual ICollection<StatusComment> StatusComments { get; set; }
}
My Member class looks like this
public class Member
{
[Key]
public int MemberID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Bio { get; set; }
public virtual ICollection<MemberCourseTaken> MemberCourseTakens { get; set; }
public virtual ICollection<Status> Statuses { get; set; }
public virtual ICollection<Club> FoundedClubs { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string Phone { get; set; }
public int AccountSourceID { get; set; }
public AccountSource AccountSource { get; set; }
public int AddressID { get; set; }
public Address Address { get; set; }
public string ProfilePhoto { get; set; }
public int MemberRankID { get; set; }
public MemberRank MemberRank { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}
And for whatever reason the database table that is created has the following columns
StatusID
Name
MemberID
PosterID
Member_MemberID
with MemberID, PosterID, and Member_MemberID being foreign keys.
How can I keep Member_MemberID from being generated?
Your Member_MemberID column is created because of the Member.Statuses property. I can imagine that this is not what you want. Probably members and statuses should exist independent of each other, so you need a junction table.
I don't know if you already use the OnModelCreating override of the DbContext, but that's the place to change the mapping between Member and Status:
protected override void OnModelCreating(DbModelBuilder mb)
{
mb.Entity<Member>().HasMany(m => m.Statuses).WithMany();
}
This will create a table MemberStatuses table with the two Id columns as foreign keys. This is a way to model a many-to-many relationship without a navigation property on the "other" side of the association. (I don't think you want a Members property in Status).
I've seen this before. In my case (Using EF 6.1), it was because my Fluent API Mapping was set up like so:
// In my EntityTypeConfiguration<Status>
HasRequired(x => x.Member).WithMany().HasForeignKey(x => x.MemberID);
That code works perfectly fine, but it doesn't tell EF that my Member class's Collection Navigational Property Status ha been taken into account. So, while I explicitly handled the existence of a Member Navigational Property in my Status Class, I now left an orphaned related collection property. That orphaned property, being a collection, tells EF that my Status class needs to have a Foreign Key to it. So it creates that on the Status Class.
To fix it, I had to be 100% explicit.
HasRequired(x => x.Member).WithMany(x => x.Statuses).HasForeignKey(x => x.MemberID)
It could bee that your Statuses Collection property in Member needs an attribute telling it that it is already considered, and not to go auto-creating mappings. I don't know that attribute.