I am rewriting an old .NET Core/EF Core 2 web app in .NET / EF Core 7.
I have the following two entities which, as far as I remember, worked fine in the old app but now I get an error
Microsoft.Data.SqlClient.SqlException (0x80131904): Introducing FOREIGN KEY constraint 'FK_ReleaseDates_Sections_SectionID' on table 'ReleaseDates' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints
I am not sure if I have always been doing something wrong in the entities and fixed it somewhere else I can't see it or if something has changed over the years and I am now doing it completely wrong.
public class Section
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Title { get; set; }
[Column(TypeName = "varchar(15)")]
public string Abbreviation { get; set; }
public int TypeID { get; set; }
public int? LogoFileID { get; set; }
public string Synopsis { get; set; }
public ICollection<ReleaseDate> ReleaseDates { get; set; }
[ForeignKey("LogoFileID")]
public SiteFile LogoFile { get; set; }
[ForeignKey("TypeID")]
public SectionType Type { get; set; }
}
public class SectionType
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
}
public class ReleaseDate
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public int VersionNumber { get; set; }
public int TypeID { get; set; }
public DateTime? Released { get; set; }
public string Platform { get; set; }
public string Region { get; set; }
public string Note { get; set; }
public int SectionID { get; set; }
[ForeignKey("SectionID")]
public Section Section { get; set; }
[ForeignKey("TypeID")]
public SectionType Type { get; set; }
}
Am I supposed to be fixing this via FluentAPI's Cascade command or is there something I am screwing up in the entities that I should be doing?
Note : This model don't work in .NET Core 2.1 and EF Core 2.1 with SQL Server. I tested and reproduced the same error.
The model has multiple cascade path :
Section -> ReleaseDate
Section -> SectionType -> ReleaseDate
And SQL Sever don't allow this. To understand, see this data :
SectionA -> ReleaseDateA
-> SectionTypeA -> ReleaseDateA
When the SectionA is removed, by cascading this remove also ReleaseDateA and SectionTypeA . And remove SectionTypeA, by cascading this remove again ReleaseDateA... ReleaseDateA is removed two times.
But this seems legit, just need to ReleaseDateA one time. Other DBMS like MySQL manage this. Then why not SQL Server?
I don't know and found no official information about this. Just found this :
SQL Server - Why can't we have multiple cascade paths?
...so instead of fixing it, the implementation avoids it by preventing the definition of duplicate cascade paths. It's clearly a short-cut...
SQL Server has this constraint and we need to live with. A solution is to avoid multiple cascade path. In your case, you can :
public class ReleaseDate
{
...
public int? TypeID { get; set; }
[ForeignKey("TypeID")]
public SectionType? Type { get; set; }
}
My project is web apllication on ASP.NET MVC 6
and basicaly I have a realy weird problem.
This is the code:
await Dashboards.UpdateReward(dashboard);
await Lessons.Update(lesson);
methods don't do anything specific but save modified states to database.
Here is what the problem is. When I start application normally and run through this part of the code it throws error:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
But here is the tricky part when I debug it and go step by step it works just fine without any error.
You may want to take a look at this to find more information about your exception:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
Thank you for your help. It would seem that the problem was in dashboard model. Lazzy loading didnt load my User property and since it is foreign key it can not be null value.
[Key, ForeignKey("User")]
public string UserId { get; set; }
//Gemification
public int Level { get; set; }
public int Experience { get; set; }
public int Yens { get; set; }
//Application
[Column(TypeName = "datetime2")]
public DateTime Created { get; set; }
[Column(TypeName = "datetime2")]
public DateTime Updated { get; set; }
public string CreatedBy { get; set; }
public string UpdatedBy { get; set; }
public virtual ICollection<Lesson> Lessons { get; set; }
public virtual ICollection<OwnedGroup> OwnedGroups { get; set; }
[Required]
public virtual ApplicationUser User { get; set; }
Any way thank you for your help.
I seen similar posts but didn't find an answer. I have WPF 4.5 application with EF 6.1.
Here is my part of my data model:
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required]
[StringLength(32)]
public string FileDisplayName { get; set; }
[Required]
[StringLength(32)]
public string FileName { get; set; }
[Required]
[StringLength(8)]
public string FileExtention { get; set; }
[StringLength(1024)]
public string Description { get; set; }
[Required]
[StringLength(1024)]
public string FilePath { get; set; }
[Required]
public DateTime UploadDate { get; set; }
[Required]
public virtual FilesTypeLookup FileType { get; set; }
[Required]
[DefaultValue(0)]
public double Amount { get; set; }
[Required]
public virtual Expenses ExpenseId { get; set; }
public virtual ExpensesCategories Category { get; set; }
public virtual ExpensesPayees Payee { get; set; }
public class ExpensesCategories
{
[Key]
[Required]
public int Id { get; set; }
[Required]
[StringLength(64)]
[Index(IsUnique = true)]
public string Name { get; set; }
[StringLength(256)]
public string Description { get; set; }
}
As you can see, File entity has ExpensesCategory navigation property.
The problem happens when I'm assigning new value for this property.
I'm using the next code to editing existing File record:
var fileEntity = entityToEdit.Files.Single(p => p.Id == file.Id);
fileEntity.Amount = file.Amount;
fileEntity.Category = DB.ExpensesCategories.Single(p => p.Id == file.Category.Id);
//more work here
context.SaveChanges();
The SaveChanges() method is firing an exception:
System.Data.Entity.Infrastructure.DbUpdateException An error occurred while updating the entries. See the inner exception for details. Int32 SaveChanges()
UpdateException An error occurred while updating the entries. See the inner exception for details. Int32 Update()
SqlException Cannot insert duplicate key row in object 'dbo.ExpensesCategories' with unique index 'IX_Name'. The duplicate key value is (חומרי יצירה).
The statement has been terminated. Void OnError(System.Data.SqlClient.SqlException, Boolean, System.Action`1[System.Action])
It seems that instead of create a relationship between existing File record to existing ExpenseCategory, EF is trying to create a new ExpenseCategory record and link it with my existing File record. The unique constraint does not allows it and fires the exception.
I don't want that EF will create new ExpenseCategory records, just want to set relationships with existing records (ExpenseCategory is look-up table).
How can I do this?
Thanks
Ofir
Can you try this, add this to the ExpensesCategories class:
public virtual ICollection<Files> Files { get; set; }
Not sure if that will fix it but it's something that's missing anyway.
If there is one to one relationship between two objects
you should add the following properties to the ExpensesCategories
[Key, ForeignKey("File")]
public int FileId {get;set;}
public virtual File File{ get; set;}
In my opinion the relation ship between ExpensesCatrgories and Files is one to many (one category has may files but each file belongs to a specific category). In this case please add
public virtual ICollection<File> Files { get; set; }
to the ExpensesCategories
I'm trying to get information from some of my models that have a foreign key relationships to my main employee model. If I map out each model individually, I can access them like normal with no problems, but I have to visit multiple different web pages to do so.
I'm trying to merge several of my models into essentially a single controller, and work with them this way. Unfortunately, when I try to access these models I get a strange error:
System.Data.SqlClient.SqlException: Invalid column name 'phone_types_phone_type_id'.
After searching through my code, apparently the only location phone_types_phone_type_id appears is in my migration code. I'm incredibly new at C# and Asp.Net in general so any help is appreciated.
Here is the code for my model:
[Table("employee.employees")]
public partial class employees1
{
public employees1()
{
employee_email_manager = new List<email_manager>();
employee_employment_history = new HashSet<employment_history>();
employee_job_manager = new HashSet<job_manager>();
employee_phone_manager = new HashSet<phone_manager>();
this.salaries = new HashSet<salary>();
}
[Key]
public int employee_id { get; set; }
[Display(Name="Employee ID")]
public int? assigned_id { get; set; }
[Display(Name="Web User ID")]
public int? all_id { get; set; }
[Required]
[StringLength(50)]
[Display(Name="First Name")]
public string first_name { get; set; }
[StringLength(50)]
[Display(Name="Last Name")]
public string last_name { get; set; }
[Column(TypeName = "date")]
[Display(Name="Birthday")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime birth_day { get; set; }
[Required]
[StringLength(1)]
[Display(Name="Gender")]
public string gender { get; set; }
[Required]
[StringLength(128)]
[Display(Name="Social")]
public string social { get; set; }
[Required]
[StringLength(128)]
[Display(Name="Address")]
public string address_line_1 { get; set; }
[StringLength(50)]
[Display(Name="Suite/Apt#")]
public string address_line_2 { get; set; }
[Required]
[StringLength(40)]
[Display(Name="City")]
public string city { get; set; }
[Required]
[StringLength(20)]
[Display(Name="State")]
public string state { get; set; }
[Required]
[StringLength(11)]
[Display(Name="Zip")]
public string zip { get; set; }
[Column(TypeName = "date")]
[Display(Name="Hire Date")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime hire_date { get; set; }
[Column(TypeName = "date")]
[Display(Name="Separation Date")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? termination_date { get; set; }
[StringLength(70)]
[Display(Name="Emergency Contact Name")]
public string emergency_contact_name { get; set; }
[StringLength(15)]
[Display(Name = "Emergency Contact Number")]
public string emergency_contact_phone { get; set; }
[Display(Name = "Notes")]
public string notes { get; set; }
public virtual ICollection<phone_manager> employee_phone_manager { get; set; }
[Table("employee.phone_manager")]
public partial class phone_manager
{
[Key]
public int phone_id { get; set; }
public int employee_id { get; set; }
[Required]
[StringLength(15)]
public string phone_number { get; set; }
[StringLength(5)]
public string phone_extension { get; set; }
public int phone_type { get; set; }
[Column(TypeName = "date")]
public DateTime date_added { get; set; }
public bool deleted { get; set; }
public virtual employees1 employees1 { get; set; }
public virtual phone_types phone_types { get; set; }
}
[Table("employee.phone_types")]
public partial class phone_types
{
public phone_types()
{
phone_manager = new HashSet<phone_manager>();
}
[Key]
public int phone_type_id { get; set; }
[Required]
[StringLength(50)]
public string phone_type_name { get; set; }
public virtual ICollection<phone_manager> phone_manager { get; set; }
}
}
And the pertinent code from my view:
#foreach (var item in Model.employee_phone_manager)
{
#Html.DisplayFor(modelItem => item.phone_number);
#: -
#Html.DisplayFor(modelItem => item.phone_type);
<br />
}
EDIT I may have found out the issue, but I'll definitely take more input if there is another option. My solution was to take and add the following: [ForeignKey("phone_type")] directly above this line: public virtual phone_types phone_types { get; set; } in my phone_manager class.
Your issue is that your connection string in data layer and connection string in web layer are pointing to different databases.
e.g.
data layer reading dev database
webapp pointing to test database.
Either update connection strings to point to the same database.
or
Make sure your both database have same tables and columns.
After doing quite a bit more research, it seems like I had a fairly unique issue. I attempted several of the fixes listed both on here and many other sites, but almost nothing seemed to fix the issue.
However, the solution I listed at the bottom of my original post seems to be working, and holding up well, so I believe it to be a fairly adequate solution to my problem.
To somewhat outline what was occurring, MVC EF was attempting to find a fk/pk relationship across two models, but since the column names across the models were different, it wasn't able to map them properly. If I were to trying to get all the emails from email_manager by using the email_types table, it wasn't an issue, but moving backwards, and grabbing the information from email_types from email_manager threw errors.
Since the column names between the two tables are different, EF tried to create a column to house the relationship, but since no such column existed, an error was thrown. To correct this, all that's necessary is to tell EF what the foreign key column actually is, and that is done by using [ForeignKey("email_type")] above the collection that houses the parent model.
So for example, my new email_types and email_manager models were as follows:
[Table("employee.email_manager")]
public partial class email_manager
{
[Key]
public int email_id { get; set; }
public int employee_id { get; set; }
[Required]
[StringLength(255)]
public string email { get; set; }
public int email_type { get; set; }
[Column(TypeName = "date")]
public DateTime date_added { get; set; }
public bool deleted { get; set; }
[ForeignKey("email_type")]
public virtual email_types email_types { get; set; }
public virtual employees1 employees1 { get; set; }
}
[Table("employee.email_types")]
public partial class email_types
{
public email_types()
{
email_manager = new HashSet<email_manager>();
}
[Key]
public int email_type_id { get; set; }
[Required]
[StringLength(50)]
public string email_type_name { get; set; }
public virtual ICollection<email_manager> email_manager { get; set; }
}
I had the similar issue. What happens is that in the database foreign keys are created and it starts mapping both the models and then throws an exception. Best way is to avoid foreign key creation by using [NotMapped] as you could use complex models and also avoid creation of Foreign Key.
You have specify the Database Table using [Table("employee.employees")]. Check your database Table is there have a column that name is phone_types_phone_type_id .It Try to find data of that column but It did not find column then throw this Message. My Problem has solve Check my database database Table.
I'm using nop commerce and to get around my problem I had to use ignore in my database map
Ignore(p => p.CategoryAttachmentType);
In the domain I had
/// <summary>
/// Gets or sets the category attachment type
/// </summary>
public CategoryAttachmentType CategoryAttachmentType
{
get
{
return (CategoryAttachmentType)this.CategoryAttachmentTypeId;
}
set
{
this.CategoryAttachmentTypeId = (int)value;
}
}
I came across the same kind of exception. My solution is to go to the model class and verify the exception given property definition/type where it defines. In here better check the Model class/classes where you define 'phone_types_phone_type_id'.
You are right.
I had similar issue.
Something like this
[ForeignKey("StatesTbl")]
public int? State { get; set; }
public StatesTbl StateTbl { get; set; }
So as you can see, I had kept name 'StateTbl' in the last line instead of 'StatesTbl'
and app kept looking for StateTblID. Then I had to change name to 'StatesTbl' instead. And then it started working well.
So now, my changed lines were:
[ForeignKey("StatesTbl")] <== 'StatesTbl' is my original States table
public int? State { get; set; }
public StatesTbl StatesTbl { get; set; }
These are in the AppDbContext.cs class file
I had an issue where I was getting the same error and I resolved it by deleting the audit trail I had created and creating a new one. I had forgotten to do this when I deleted some columns from the table earlier on.
My problem is that I forgot that I've created several SQL Views in my database.
I've used those views in my ASP.NET C# MVC app.
So when I received error I naturally checked all databases tables but forgot about views in which I didn't add new fields.
I am using entity framework (for learning) to create the datatable; however, when I run the application, it creates the database column name as: AnaKategori_ANA_CATEGORY_ID.
Why is it doing that since I am specifically telling it to name the column as "ANA_CATEGORY_ID"?
Below is the class files content.
[Table("CATEGORY")]
public class Kategori
{
[Key]
public Guid CATEGORY_ID { get; set; }
[MaxLength(100)]
public string CATEGORY { get; set; }
[MaxLength(100)]
public string CATEGORY_TR { get; set; }
[Column("ANA_CATEGORY_ID")]
public virtual AnaKategori AnaKategori { get; set; }
}
I tried boindiil's answer prior to posting (which was to use ForeignKey Attribute and I got this error:
The ForeignKeyAttribute on property 'AnaKategori' on type 'BusinessListingMVC.Models.Kategori' is
not valid. The foreign key name 'ANA_CATEGORY_ID' was not found on the dependent type
BusinessListingMVC.Models.Kategori'.
The Name value should be a comma separated list of foreign key property names.
Description: An unhandled exception occurred during the execution of the current web request.
Please review the stack trace for more information about the error and where it originated in
the code.
I have found this link, which points out that this seems to be a bug. In this case you have to use the [ForeignKey] attribute to give it the desired name:
[Table("CATEGORY")]
public class Kategori
{
[Key]
public Guid CATEGORY_ID { get; set; }
[MaxLength(100)]
public string CATEGORY { get; set; }
[MaxLength(100)]
public string CATEGORY_TR { get; set; }
[Column("ANA_CATEGORY_ID")]
public Guid ANA_CATEGORY_ID { get; set; }
[ForeignKey("ANA_CATEGORY_ID")]
public virtual AnaKategori AnaKategori { get; set; }
}