SQLException: Multiple Cascade Paths? - entity-framework

I have the following model:
public class Job
{
[Key]
public int JobId { get; set; }
public string Description { get; set; }
public DateTime DateCreated { get; set; }
public DateTime? DueDate { get; set; }
public int JobIdentity { get; set; }
[MaxLength(50, ErrorMessage = "Please ensure the Job Title is less than 50 characters")]
public string JobTitle { get; set; }
public int Priority { get; set; }
// Relationships
[ForeignKey("Category")]
public int CategoryId { get; set; }
[ForeignKey("JobType")]
public int JobTypeId { get; set; }
[ForeignKey("UserRequestedBy")]
public int RequestedBy { get; set; }
[ForeignKey("UserCreatedBy")]
public int CreatedBy { get; set; }
// Navigation Properties
public virtual JobType JobType { get; set; }
public virtual Category Category { get; set; }
public virtual User UserRequestedBy { get; set; }
public virtual User UserCreatedBy { get; set; }
public virtual ICollection<Task> Tasks { get; set; }
public virtual ICollection<JobNote> Notes { get; set; }
}
But when I try to run my application I get the following error:
Introducing FOREIGN KEY constraint 'FK_dbo.Jobs_dbo.Users_CreatedBy' on table 'Jobs' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.

With cascade delete on by default, deleting a User has two cascade paths - RequestedBy and CreatedBy
Disabling the cascade deletion is exhibited in this question.

Related

.NET 5.0 - EF - DbSet is empty after upgrade from 3.1

One of my DbSet returns an empty list, while data is there in db, and it used to work before upgrading to .NET 5.0
var list = await context.TeamMembers.ToListAsync(); >> returns empty list
var list = await context.TeamMembers.Include(t=>t.User).ToListAsync(); >> returns empty list
while others are working correctly returning a populated list
var list2 = await context.Users.ToListAsync(); >> works fine
my dbsets are define like this
public DbSet<User> Users { get; set; }
public DbSet<TeamMember> TeamMembers { get; set; }
here is my table structure
CREATE TABLE [dbo].[teamMembers] (
[Id] INT IDENTITY (1, 1) NOT NULL PRIMARY KEY,
[UserId] INT NOT NULL,
[PartnerId] INT NOT NULL,
[Type] INT NOT NULL,
[CreationDate] DATETIME DEFAULT (getdate()) NOT NULL,
[ModificationUserId] INT NOT NULL,
[ModificationDate] DATETIME DEFAULT (getdate()) NOT NULL,
CONSTRAINT [FK_teamMembers_Members] FOREIGN KEY ([UserId]) REFERENCES [users]([Id]),
CONSTRAINT [FK_teamMembers_Partners] FOREIGN KEY ([PartnerId]) REFERENCES [partners]([Id]),
CONSTRAINT [FK_teamMembers_ModificationUser] FOREIGN KEY ([ModificationUserId]) REFERENCES [users]([Id]),
);
and here is my object
[Table("teamMembers")]
public class TeamMember
{
[Required]
public int? Id { get; set; }
[Required]
public User User { get; set; }
[Required]
public int? PartnerId { get; set; }
[Required]
public int Type { get; set; } // 0 agency 1 Salesman
[Required]
public DateTime CreationDate { get; set; }
[Required]
public DateTime ModificationDate { get; set; }
[Required]
public int ModificationUserId { get; set; }
}
[edit]
here is the query generated by EF, if I run it manualy it returns data
(there is a joint in this one as I used .Include(...) )
SELECT [t].[Id], [t].[CreationDate], [t].[ModificationDate], [t].[ModificationUserId], [t].[PartnerId], [t].[Type], [t].[UserId], [u].[Id], [u].[Civility], [u].[CreationDate], [u].[CreationUserId], [u].[Email], [u].[FirstName], [u].[Identifier], [u].[Language], [u].[LastName], [u].[Login], [u].[LoginEnabled], [u].[Mobile], [u].[ModificationDate], [u].[ModificationUserId], [u].[MustResetPassword], [u].[Password], [u].[Phone], [u].[Position], [u].[ResetPasswordDate], [u].[ResetPasswordToken], [u].[RoleId], [u].[Type]
FROM [teamMembers] AS [t]
LEFT JOIN [users] AS [u] ON [t].[UserId] = [u].[Id]
here is the User class
public class User
{
[Required]
public int? Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string Email { get; set; }
public string Login { get; set; }
[Required]
public DateTime CreationDate { get; set; }
[Required]
public DateTime ModificationDate { get; set; }
[Required]
public int CreationUserId { get; set; }
[Required]
public int ModificationUserId { get; set; }
[Required]
public short RoleId { get; set; }
[Required]
public short Civility { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
[Required]
public string Position { get; set; }
[Required]
public short Language { get; set; }
[Required]
public bool MustResetPassword { get; set; }
[Required]
public short Type { get; set; } // professional/private
public string Identifier { get; set; }
[JsonIgnore]
public string Password { get; set; }
[Column(TypeName = "BIT")]
public bool LoginEnabled { get; set; }
public string ResetPasswordToken { get; set; }
public DateTime? ResetPasswordDate { get; set; }
}
here is the partner class
public class Partner
{
[Required]
public int? Id { get; set; }
public Company Company { get; set; }
[Required]
public User Manager { get; set; }
public List<Invoice> Invoices { get; set; }
[NotMapped]
public double InvoicesAmount { get; set; }
[Required]
public List<ProductRetribution> ProductsRetributions { get; set; }
[Required]
public double Won { get; set; }
[Required]
public double Pending { get; set; }
[Required]
public double Offset { get; set; }
// following fields are created by the system, inputs from client are discarded, no validation , but needed for mvc
[Required]
public DateTime CreationDate { get; set; }
[Required]
public DateTime ModificationDate { get; set; }
[Required]
public int ModificationUserId { get; set; }
}
is there anything I am missing ?
thanks for your help
as it turns out, I was checking the wrong db
the actual db has it's table completely empty
moral of the story : don't mix 3 versions of your database on the dev server
thanks for everyone helping me out, I'll surely fix all my nullables in my tables

How to solve ' Introducing FOREIGN KEY constraint 'FK' on table 'Table' may cause cycles or multiple cascade paths?

I have a problem with migrations in EF Core 5.0 :
Introducing FOREIGN KEY constraint 'FK_Trades_Signals_SignalID' on
table 'Trades' may cause cycles or multiple cascade paths. Specify ON
DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY
constraints.
Here is the tables:
public class Signal
{
public int SignalID { get; set; }
public Type Type { get; set; }
public int Buy { get; set; }
public int Sell { get; set; }
public int Neutral { get; set; }
[Required]
public int CoinID { get; set; }
public virtual Coin Coin { get; set; }
public int? TradeID { get; set; }
public Trade Trade { get; set; }
}
public class Trade
{
public int TradeID { get; set; }
[Required]
public int CoinID { get; set; }
public virtual Coin Coin { get; set; }
public DateTime TradeDate { get; set; }
[Column(TypeName = "decimal(16,8)")]
public decimal Price { get; set; }
[Column(TypeName = "decimal(16,8)")]
public decimal Amount { get; set; }
public TradeStatus Status { get; set; }
[ForeignKey("Signal")]
public int? SignalID { get; set; }
public virtual Signal Signal { get; set; }
[Column(TypeName = "decimal(8,2)")]
public decimal ProfitLoss { get; set; }
}
I have tried lots of things, but continue to get errors.
I tried this with the same error:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Trade>().HasOne<Signal>(s => s.Signal).WithOne(t => t.Trade).OnDelete(DeleteBehavior.NoAction);
}
Please help.

EF 6 cycles or multiple cascade paths

I'm trying to create my database from my models, but I keep getting the error Introducing FOREIGN KEY constraint 'FK_dbo.Reports_dbo.UserProfiles_UserId' on table 'Reports' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
anyone knows what might be wrong with my models/setup?
These are all used Models
public class Report {
[Key]
public int Id { get; set; }
[Required]
public string Number { get; set; }
public bool Synced { get; set; }
public DateTime CreationDate { get; set; }
public int NewCommentId { get; set; }
public virtual Comment NewComment { get; set; }
public int UserId { get; set; }
public virtual UserProfile User { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Photo> PhotosBefore { get; set; }
public virtual ICollection<Photo> PhotosAfter { get; set; }
}
public class Photo {
[Key]
public int Id { get; set; }
public string Image { get; set; }
public bool Synced { get; set; }
public DateTime CreationDate { get; set; }
public int ReportId { get; set; }
public virtual Report Report { get; set; }
public int UserId { get; set; }
public virtual UserProfile User { get; set; }
}
public class Comment {
[Key]
public int Id { get; set; }
public DateTime CreationDate { get; set; }
public string Text { get; set; }
public int ReportId { get; set; }
public virtual Report Report { get; set; }
public int UserId { get; set; }
public virtual UserProfile User { get; set; }
}
public class UserProfile {
[Key]
public int Id { get; set; }
public string Stamnummer { get; set; }
public string Leverancier { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Report> Reports { get; set; }
public virtual ICollection<Photo> Photos { get; set; }
}
In order to be certain, we need to see how you have configured your relationships using the model builder in the OnModelCreating method. Based on the error message you have provided, it appears that you have relationships configured so that one of your entities is configured for cascade on delete from two or more other entities.
As an example (this may not be the case, but rather just a means of describing the problem):
User has a one-to-many relationship with Comments
User has a one-to-many relationship with Reports
Report has a one-to-many relationship with Comments
Comment is configured so that a User is required
Comment is configured so that a Report is required
Report is configured so that a User is required
Any one-to-many relationship where the entity one side of the relationship is required is going to have cascade on delete configured by default. In this scenario, if a User were deleted it would trigger a cascade to both Reports and Comments. Each Report would also cause a cascade on Comments.
The solution is to disable cascading deletes for one of the relationships. You can find a similar question to yours here describing what I mentioned above.

EF code first model not in sync with database

My EF Code First model for some reason is not in sync with the db. I'm getting this error:
{"Invalid column name 'Type_Id1'."}
The field is actually called 'Type_Id' so I'm not sure from where that 1 comes up. I have the table column called as Type_Id and also I've added a Type_Id in my type entity model.
Why might I be getting that error message, plus why I'm getting 1 at the end of the name?
Update
My Task class:
public class Task
{
public Task()
{
Language = 1;
Grades = new HashSet<Grade>();
Categories = new HashSet<Category>();
Subjects = new HashSet<Subject>();
Rooms = new Collection<Room>();
Tools = new Collection<Tool>();
}
[Key]
public int Id { get; set; }
public string Description { get; set; }
public virtual TaskType Type { get; set; }
public string Rules { get; set; }
[Required]
[StringLength(200), MinLength(1)]
public string Name { get; set; }
public int PreperationTime { get; set; }
public int InstructionTime { get; set; }
public int TaskTime { get; set; }
public int Type_Id { get; set; }
public string VideoLink { get; set; }
[Required]
public int Language { get; set; }
public int? MinimumParticipants { get; set; }
public int? MaximumParticipants { get; set; }
public int? Rating { get; set; }
[Required]
public string CreatedBy { get; set; }
public virtual ICollection<Grade> Grades { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
public virtual ICollection<Tool> Tools { get; set; }
}
DBContext class:
public ApplicationDbContext() : base("DefaultConnection", false)
{
}
public DbSet<Task> Tasks { get; set; }
public DbSet<TaskType> TaskTypes { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
You need to add the FK attribute on your navigation property. EF is creating Type_Id1 because Type_Id already exists (although it can't tell by convention it is the FK).
[ForeignKey("Type_Id")]
public virtual TaskType Type { get; set; }
https://msdn.microsoft.com/en-us/data/jj591583.aspx#Relationships

Table with INSERT statement conflict in totally different table

I am getting the following error.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.NotificationObject_dbo.Comment_CommentReplyID". The conflict occurred in database "DB_f0f7b19b55c44199988352815f71b25c", table "dbo.Comment", column 'CommentID'.
I'm confused, because the NotificationObject table can have a wide variety of optional foreign keys, including a key to a comment, or a reply to a comment. When I try to add a row with a CommentReplyID, it gives the error above... about the comment table??? The key should point to the CommentReply table, so I'm pretty confused.
See the related models below.
public class NotificationObject
{
public int ID { get; set; }
public int NotificationTypeID { get; set; }
public int? CommentID { get; set; }
public int? CommentVoteID { get; set; }
public int? CommentReplyID { get; set; }
public int? CommentReplyVoteID { get; set; }
public int? UserID { get; set; }
public int? ActivityCommentID { get; set; }
public DateTime DateCreated { get; set; }
public virtual NotificationType NotificationType { get; set; }
public virtual Comment Comment { get; set; }
public virtual Comment CommentVote { get; set; }
public virtual Comment CommentReply { get; set; }
public virtual Comment CommentReplyVote { get; set; }
public virtual ActivityComment ActivityComment { get; set; }
public virtual ICollection<NotificationActor> NotificationActor { get; set; }
}
public class Comment
{
public int CommentID { get; set; }
public int ProjectDocID { get; set; }
public int UserID { get; set; }
public string text { get; set; }
public string quote { get; set; }
public DateTime DateCreated { get; set; }
public virtual ICollection<CommentVote> CommentVote { get; set; }
public virtual ICollection<CommentReply> CommentReply { get; set; }
public virtual ICollection<CommentReport> CommentReport { get; set; }
public virtual ProjectDoc ProjectDoc { get; set; }
public virtual User User { get; set; }
public virtual ICollection<ranges> ranges { get; set; }
}
Why wont it let me add a value to the CommentReplyID field in the NotificationObject table?
Your CommentReply navigation property in NotificationObject targets Comment type, not CommentReply type.