EntityFramework 6.1 Add Method - entity-framework

I have a very simple problem. Always use like this, but now not working, why i dont know.
I'm working on MVC 4 and Entity Framework 6.1.
I have sql table like picture below which name is Kategori,
Translation: KategoriID -> CategoryID, KategoriIsmi -> Category, UstKategoriId -> ParentCategoryID
KategoriID column has also, Primary Key and Identity Specification YES (Identity Increment 1, Seed 1)
And this is my Kategori Model class
public class Kategori
{
[Key]
public byte? KategoriID { get; set; }
[Required(ErrorMessage = "Please insert category name")]
public string KategoriIsmi { get; set; }
public byte? UstKategoriID { get; set; }
}
And my save code with EntityFramework
public void AddNewItem(Kategori item)
{
using (EmlakCMSContext _ent = new EmlakCMSContext())
{
_ent.Kategori.Add(item);
_ent.SaveChanges();
}
}
When I run this code
Income data (for save in db)
I have a error. And I write code, watch the error in IntelliTrace.
Error Translate: KategoriID alanı gereklidir -> CategoryID field is required.
But KategoriID field have set auto increment true.
How can i solve this problem? Thanks.

It's hard to tell as the error message is not in English. However, your primary key should not use a nullable data type. Change this:
public byte? KategoriID { get; set; }
To this:
public byte KategoriID { get; set; }
You may also need to tell entity framework that the column is an IDENTITY column:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public byte KategoriID { get; set; }

Related

Entity Frameworks Creates Auto Column

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.

Cannot insert the value NULL into column BLAH table BLAH column does not allow nulls. INSERT fails

I have a domain entity that has
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
set on the Id property but EF is still trying to insert a null value when attempting to save it. Is this a common problem? This is an example of what it looks like.
public class Invoice
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public ShippingInformation ShippingInformation{ get; set; }
public BillingInformation BillingInformation { get; set; }
public decimal Subtotal { get; set; }
public User user { get; set; }
public bool Processed { get; set; }
}
There is a bug in the Entity Framework where migrations won't properly detect changes to DatabaseGeneratedOption.
See this issue on the Entity Framework page on the Codeplex website for a description of the problem and an example of how to recreate it.
If you can add this attribute [DatabaseGenerated(DatabaseGeneratedOption.None)]with key, it worked for me with entity framework 6.1.3.
For Example,
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
Public int EmployeeId { get; set; }

Table Per Hierarchy & Inherited Relationships

I'm using Entity Framework 5, targeting .Net 4.5. For the life of me I can't figure out what I'm doing wrong that's causing the following error while trying to work with Table Per Hierarchy and Navigation columns:
Invalid column name 'Game_Category'.
Invalid column name 'Game_Value'.
Invalid column name 'Type_Category'.
Invalid column name 'Type_Value'.
Here's the abstract base class (note the composite PK on Category and Value):
[Table("Dictionary")]
public abstract class Lookup
{
[Key, Column(Order = 0)]
[StringLength(50)]
public string Category { get; set; }
[StringLength(100)]
public string ExtendedValue { get; set; }
[Required]
public bool IsActive { get; set; }
[Required]
[StringLength(50)]
public string Key { get; set; }
[Key, Column(Order = 1)]
public int Value { get; set; }
}
Followed by two subclasses that add no additional columns...
public class Game : Lookup {}
public class SetType : Lookup {}
Here's the class with Navigation properties to Game and SetType...
public class CardSet
{
[Required]
[StringLength(10)]
public string Abbreviation { get; set; }
public virtual Game Game { get; set; }
[Required]
public int GameId { get; set; }
[Key]
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
public DateTime ReleaseDate { get; set; }
public virtual Lookup Type { get; set; }
[Required]
public int TypeId { get; set; }
}
From my data context...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Lookup>()
.Map<Game>(l => l.Requires("LookupType").HasValue("Game"))
.Map<SetType>(l => l.Requires("LookupType").HasValue("Set Type"));
base.OnModelCreating(modelBuilder);
}
The lookup table has a discriminator column named LookupType. I've read through several tutorials on table/inheritance. The other two - TPT and TPC using similarly built objects were a cinch. While I understand the errors above - that it's looking for FK columns by convention, I don't understand what I'm doing wrong or missing that's causing it to look for those columns. I've tried placing ForeignKey attributes over the GameId and TypeId properties, but then I get errors about dependent/principal relationship constraints and I'm not sure how to specify the category as an additional foreign key.
I have yet to find a tutorial on table/inheritance that goes over navigation properties as I'm using them. Any help would be greatly appreciated, this has been driving me nuts for over an hour.
Update:
I believe the problem lies in the use of Category as part of the key. The CardSet doesn't have two properties for the category of "Game" for that lookup or the category for "Set Type" for that lookup. I tried creating these properties but that didn't work. Is it possible to set those using the Fluent API? I've made about a dozen attempts so far without any luck.
I think that EF does not "like" the construct modelBuilder.Entity<Lookup>() to map the two sub classes. This should help:
modelBuilder.Entity<Game>()
.Map(l => l.Requires("LookupType").HasValue("Game"));
modelBuilder.Entity<SetType>()
.Map(l => l.Requires("LookupType").HasValue("Set Type"));

How can I update a Code First application to accommodate manual schema changes?

I have an app that was created using EF. The problem is that I noticed some extraneous foreign keys columns created in one of the tables. Dropping these columns causes an [SqlException (0x80131904): Invalid column name 'Material_Id' error.
Here is a simplified version of the class structure...
public class Hazard
{
public int Id { get; set; }
public string Name { get; set; }
}
public abstract class HazardAnalysis
{
public int Id { get; set; }
public int HazardId { get; set; }
public virtual Hazard Hazard { get; set; }
}
public class ProductHazard : HazardAnalysis
{
public int ProductId { get; set; }
public virtual Product Product { get; set; }
}
The table that was generated looked like this...
dbo.Hazards
Id int
Name string
Product_Id int
Since the relationship between ProductHazards and Hazards is 1:many, the Product_Id field should not be there. Dropping this column generates the Invalid column name 'Product_Id' error.
I've scoured the model for hours and can't find any valid reason for this column to exist.
Is there any way to update the model after manually dropping a column? I obviously don't want to drop and recreate the database.
I've also noticed that the productId of the current product is inserted in the dbo.Hazards Product_Id table whenever a new ProductHazard is created. Since there is a many-to-one relationship between ProductHazards and Hazards, when a new ProductHazard is created, the Product_Id field is updated with the ProductId of the new ProductHazard, which seems bizarre.
Any advice would be greatly appreciated.
Here is the DbSet code:
public DbSet<Hazard> Hazards { get; set; }
public DbSet<HazardAnalysis> HazardAnalyses { get; set; }
and also...
modelBuilder.Entity<HazardAnalysis>()
.HasRequired(e => e.Hazard)
.WithMany()
.HasForeignKey(e => e.HazardId)
.WillCascadeOnDelete(false);
You need to define the many part of the relationship. In this case, you need to add a collection property to your Hazard object, like below:
public class Hazard
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<HazardAnalysis> HazardAnalyses { get; set; }
}

Invalid Column Name with EF

I modified the table UserProfile in the database with some extra columns and then modified the UserProfile class to reflect them:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public string School { get; set; }
}
Obviously they are FirstName, Surname and School. For some reason though despite the register action saving details into all 3 of these new columns when I try to load the data via:
var context = new UsersContext();
var user = context.UserProfiles.First(n => n.UserName == model.UserName);
It says that School is an invalid ColumnName. I checked it was a string in both class and table so bit confused how to debug, help!
(Continued from comments on OP)
Rather than doing this manually, you should consider using the EF migrations framework - There are a number of benefits and it's more future-proof in case internal EF functionality changes.
See here for more information on migrations