I am newbie to Entity Framework Code First approach.
I was created the following Genre model:
public class Genre
{
public byte Id { get; set; }
public string Name { get; set; }
}
then add migration and update database.
After that I create The following Movie Model
public class Movie
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
public int NumberInstock { get; set; }
public Genre Genre { get; set; }
}
then add migration and update the database which generate a 'Genre_Id' column as a foreign key.
I try to add the following property to the MovieModel
public byte Genre_Id { get; set; }
but when I run the application I got the error Invalid column name 'Genre_Id1'.
I don't have a column name like this.
The solution is when I added a Genre navigation property to MovieModel I should add GenreId property also the add migration and update-database. That means add the navigation property and the property together then add migration and update database
Related
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.
This is my model (semplified):
PRAT is the main table
public partial class PRAT
{
public int ID { get; set; }
public string PRATICA { get; set; }
public int ANNO { get; set; }
public string VARIANTE { get; set; }
[ForeignKey("ID")]
public VW_PRATICHE_CONTIPO VW_PRATICHE_CONTIPO { get; set; }
}
VW_PRATICHE_CONTIPO is a View (not a table!) in the database that contains some data related to PRAT table
public class VW_PRATICHE_CONTIPO
{
public int ID { get; set; }
public DateTime? DATAPRES { get; set; }
public string PROTGEN { get; set; }
public string TIPO { get; set; }
public string TIPOEXTRA { get; set; }
public string TIPOISTANZA { get; set; }
public string TIPOPRAT { get; set; }
}
The one-to-one relation between the table and the View is based on the ID field.
I need this because I want to do a query like this:
context.PRAT.Include(x=> x.VW_PRATICHE_CONTIPO)
This query works as exptected.
The problem happens when I try to save a new entity in PRAT.
When i do this:
context.PRAT.Add(prat);
await context.SaveChangesAsync();
I got this error:
The property 'ID' on entity type 'PRAT' has a temporary value. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.
If I remove the navigation property from PRAT all works fine, but I can't do the Include in my Query.
Can anybody help me?
Thank you.
I'm using ASP.NET Core and EF Core and I have the two following parent and child classes. Each gift card can have many transactions:
public class GiftCard
{
public int Id { get; set; }
public string BarCode { get; set; }
public DateTime PurchaseDate { get; set; }
public string Comments { get; set; }
public byte[] Timestamp { get; set; }
public List<Transaction.Transaction> Transactions { get; set; }
}
public class Transaction
{
public int Id { get; set; }
public DateTime TransactionDate { get; set; }
public decimal TransactionAmount { get; set; }
public TransactionType TransactionType { get; set; }
public byte[] Timestamp { get; set; }
public GiftCard.GiftCard GiftCard { get; set; }
}
Based on what I read, this is the way to do it, by having navigation property on the parent and reference navigation in child. When I add my migrations and update the database using the command line, everything seemed ok in the database except that the GiftCardId foreign key in the Transactions table is nullable. I want to make sure this is NOT NULL. Am I missing a Data Annotation attribute?
Put the following property on your Transaction entity, and it should be resolved.
public int GiftCardId { get; set; }
What is happening with your definition is that a shadow property is being created and EF's Change Tracker is maintaining the relationships.
See here.
Suppose I have these two POCOs:
public class Album {
public int ID { get; set; }
[Required]
public string Title { get; set; }
public short Rating { get; set; }
public int ArtistID { get; set; }
[Required]
public virtual Artist Artist { get; set; }
}
public class Artist {
public int ID { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Album> Albums { get; set; }
}
and then I execute some code like this:
using (PickContext db=new PickContext()) {
Album pick=db.Albums.SingleOrDefault(a => a.ID==pickID);
if (pick==null) return;
pick.Rating=4;
db.SaveChanges();
I was surprised that I got a validation exception like this:
Property: "Artist", Error: "The Artist field is required."
When I changed my query to include the Artist:
Album pick=db.Albums.Include("Artist").SingleOrDefault(a => a.ID==pickID);
I no longer got the exception. If I don't tell EF to populate all properties, and they're not required, will it simply overwrite these FKs in the database? I would have thought that if I retrieve an entity and don't assign a property, the property won't be changed in the database. Is this not true?
You don't need to use the required attribute for the Artist. It simply telling to EF your navigation property is always required to be there. Since you have defined,
public int ArtistID { get; set; }
as not nullable the ArtistID will be required in the in the database level (I think that is what you expected from the required attribute here). I think you can just remove the required attribute and then this should be working as expected.
I'm having an issue that i just can't seem to figure out. Lets say I have 2 Entities defined in my domain; Person and Document. Below is the definition for Document :
public class Document
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Title { get; set; }
public DateTime Date { get; set; }
public virtual Person Owner{ get; set; }
public virtual Person AssignedTo { get; set; }
}
Now, when EF CTP4 creates the SQL table on initialize, there is only one field mapping to a Person.Id being Owner_id. Whatever i try, the field for AssignedTo is never created.
Anything that could solve this?
Regards,
avsomeren
Your code perfectly created the desired schema in the database for me:
If you don't get this schema in you DB then my guess is that something is not right with the rest of your object model. Could you post your full object model please?
Another Solution:
While your current Document class will give you the desired results, but you can still take advantage of the Conventions for Code First and explicitly specify the FKs for your navigation properties:
public class Document
{
public int Id { get; set; }
[Required][StringLength(255)]
public string Title { get; set; }
public DateTime Date { get; set; }
public int OwnerID { get; set; }
public int AssignedToID { get; set; }
public virtual Person Owner { get; set; }
public virtual Person AssignedTo { get; set; }
}
Code First will now infer that any property named <navigation property name><primary key property name> (e.g. OwnerID), with the same data type as the primary key (int), represents a foreign key for the relationship.
This essentially results to the same DB schema plus you have the FKs on your Document object as well as navigation properties which gives you ultimate flexibility to work with your model.