How do I make this Code First relationship not required - entity-framework

In my Code First for this application I have defined a foreign key as nullable. However, when I try to add a record without that key, I still get a Foreign Key constraint error:
The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_dbo.RequestReview_dbo.CustomForm_ReviewFormId\". The conflict occurred in database \"Mkp\", table \"dbo.CustomForm\", column 'CustomFormId'.\r\nThe statement has been terminated.
How should I be defining the relationship so that the key constraint is not enforced?
My code first model defines the field like this:
[Key, ForeignKey("Resource"), DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid RequestReviewId { get; set; } // My Primary Key
public virtual Resource Resource { get; set; }
public Guid? ReviewFormId { get; set; } // Foreign Key
[ForeignKey("ReviewFormId")]
public CustomForm ReviewForm { get; set; }
(I did try searching, but I'm not sure I searched with the right terminology.)
Edit/Update:
If I remove the ForeignKey tag, I still get migration trying to create a relationship, but this time called ReviewForm_CustomFormId. How can I avoid this?
Updated version of the model:
[Key, ForeignKey("Resource"), DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid RequestReviewId { get; set; } // My Primary Key
public virtual Resource Resource { get; set; }
public Guid? ReviewFormId { get; set; } // Foreign Key
public CustomForm ReviewForm { get; set; }

Give it a separate primary key field as well as your foreign key:
public int ID { get; set; }
public Guid? ReviewFormId { get; set; }
[ForeignKey("ReviewFormId")]
public CustomForm ReviewForm { get; set; }
Doing this I was able to insert records that have a null ReviewFormId.

One solution i see is that you could use this colunm ReviewFormId as an implicite foreign key. What i mean is : don't define it as a foreign key, just a regular data instead, and only YOU will know that the data inside it represent a foreign key, but don't tell entity that it is a foreign key because GUID just dosen't accept nullable foreign key.

Related

Ef core and multiple parent entities use list of the same child entity?

Is there an easy way to have a setup like this in EF Core?
ProjectEntity
Id
Name
List<Notes>
CustomerEntity
Id
Name
List<Notes>
NotesEntity
Id
Date
Note
Every parent entity would have a one-to-many relation to same child entity. So I can not use normal behavior as
NotesEntity
Id
ParentId
Date
Note
I have some idea to have like above but also add one field that said what the parent entity is, is that the right way to do it or is there a better way? If I use this way I can't use EF Core normal behavior with one-to-many relationship? I need to make more manual work for search / add and so on?
Edit :
Entity Framework multiple parent tables I found this solution, but there I need to make a connection from my child to every parent I use, it could be alot of them.
Did also find a solution like :
BaseEntity
List<Notes>
ProjectEntity:BaseEntity
NotesEntity
Id
BaseEntityId
...
This last solution maybe is the best way to do it if I have alot of parent entities?
[EDIT 220922]
Could [Owned] type has collection of other Items? Or this feature won't work on owned entitys? I guess this behavior isn't supported?
[Owned]
public class Note
{
public int Id { get; set; }
public string Text { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public ICollection<string> Tags { get; set; }
}
I got an error on ICollection-row when I try to add-migration.
Unabel to determine the relationshop represented by navigation ... of
typ 'ICollection' Either manually configure the relationship, or
ignore this property using the '[NotMapped]' attribute.....
Maybe I could have one middleentity like :
public class NoteTagsEntity
{
public int Id { get; set; }
public ICollection<string> Tags { get; set; }
}
And then :
[Owned]
public class Note
{
public int Id { get; set; }
public string Text { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public int NoteTagsId { get; set; }
public NoteTagsId NoteTagsId { get; set; }
}
Edit
I solved the Note functionality with having more FK's, one that point to Id of parent and one FK Id that point to what module that use that particular note. Here I don't have parent - child relation in my entities, I need to do this connection by myself but in this way it's easy to apply more modules that use note's later.
Use Owned Entity Types, and each entity will get its own notes table.
eg
public abstract class Entity
{
public int Id { get; set; }
}
public abstract class EntityWithNotes: Entity
{
public virtual ICollection<Note> Notes { get; set; }
}
[Owned]
public class Note
{
public int Id { get; set; }
public string Text { get; set; }
}
public class Project : EntityWithNotes
{
public string Name { get; set; }
}
public class Customer : EntityWithNotes
{
public string Name { get; set; }
}
creates
CREATE TABLE [Customer_Notes] (
[Id] int NOT NULL IDENTITY,
[CustomerId] int NOT NULL,
[Text] nvarchar(max) NOT NULL,
CONSTRAINT [PK_Customer_Notes] PRIMARY KEY ([CustomerId], [Id]),
CONSTRAINT [FK_Customer_Notes_Customer_CustomerId] FOREIGN KEY ([CustomerId]) REFERENCES [Customer] ([Id]) ON DELETE CASCADE
);
CREATE TABLE [Project_Notes] (
[Id] int NOT NULL IDENTITY,
[ProjectId] int NOT NULL,
[Text] nvarchar(max) NOT NULL,
CONSTRAINT [PK_Project_Notes] PRIMARY KEY ([ProjectId], [Id]),
CONSTRAINT [FK_Project_Notes_Project_ProjectId] FOREIGN KEY ([ProjectId]) REFERENCES [Project] ([Id]) ON DELETE CASCADE
);

Entity Framework code-first : How to fix error with self-reference foreign key in SQL using Annotations

I have trouble with the database, I use a table t_CTDaotao sc_HeNganh. The problem here is that the self-referencing key t_CTDaotao1 can only refer to sc_HeNganh1, and the key t_CTDaotao2 cannot reference sc_HeNganh2, more correctly it only reference 1 key, not multiple keys
enter image description here
enter image description here
You need to put the [ForeignKey] attributes on the navigation properties, not the foreign key columns.
Please try this:
public int MaHN { get; set; }
public int MaKhoi { get; set; }
[ForeignKey("sc_HeNganh")]
public virtual sc_HeNganh sc_HeNganh { get; set; }
[ForeignKey("sc_Khoilop")]
public virtual sc_Khoilop sc_Khoilop { get; set; }

How do I override entity framework code first convention for creating a foreign key

I have a property on my items class called vend_id which of course EF thinks is a foreign key to the vendor table. It actually should be a foreign key in the database but for reasons unknown to me the designers of the db chose not to make it a foreign key.
I am using EF to create a copy of the db schema on the local machine. When EF creates the database I want to tell it not to create a foreign key on the vend_id column. How do I do that? Ideally I do not want to rename the property because there are several such instances in my db and it just makes it confusing.
Thank you,
Sam
You can't have a navigation property to a Vendor entity in your Item entity class if the Items table does not have a foreign key to table Vendor. If you did not specify a navigation property in entity class Item, EF would not infer that vend_id is a foreign key.
Update:
Unable to reproduce with the following:
[Table("EntityA")]
public partial class EntityA
{
public int Id { get; set; }
public Nullable<int> EntityBId { get; set; }
public string Description { get; set; }
[ForeignKey( "EntityBId" )]
public virtual EntityB EntityB { get; set; }
// this is not created as a FK
// nor does EntityCId cause a FK
public int EntityC_Id { get; set; }
}
[Table("EntityC")]
public class EntityC
{
public EntityC()
{
EntitiesD = new HashSet<EntityD>();
}
public int EntityCId { get; set; }
public string Name { get; set; }
public virtual ICollection<EntityD> EntitiesD { get; set; }
}

Asp.net mvc entity framework code first associate foreign key with different name

How can I associate a foreign key with different names here: createdby in post and UserID in users table.
public class Post : IValidatableObject
{
[Key]
public long PostID { get; set; }
public long? ParentPostID { get; set; }
[ForeignKey("CreatedBy")]
public virtual User Users { get; set; }
[ScaffoldColumn(false)]
public DateTime? CreatedDate { get; set; }
[ScaffoldColumn(false)]
public long? CreatedBy { get; set; }
}
public class User
{
[Key]
public long UserID { get; set; }
[Required]
[MaxLength(20)]
[Display(Name = "User Name")]
public string UserName { get; set; }
}
Your mapping is correct - especially the [ForeignKey("CreatedBy")] attribute, you don't need to change anything.
In a foreign key relationship in Entity Framework the dependent (= Post) and its foreign key always refers to the primary key of the principal (= User) - and the primary key is UserID - by convention and also because you have marked it with the Key attribute. There is nothing you need to specify anymore.
Your relationship is optional (0..1-to-many) because the foreign key CreatedBy is nullable (long?). So there can be posts in the database which haven't been created by any user. If you don't want this, you can make the relationship required by using a non-nullable foreign key property (long CreatedBy).

Enable cascading deletes in EF Code First without exposing foreign key

When performing a delete of a one-many relationship without exposing the foreign key, EF deletes the parent record and tries to null the foreign key on the child records. This of course causes an error because the foreign key is not nullable. Adding the foreign key to the child class overrides this behavior, but I'd rather not expose it.
For example given the following two classes, I'd prefer not to have JobId as a property of the Project class.
public class Job : ModelBase
{
[Required]
[StringLength(100)]
public string Company { get; set; }
[Required]
[StringLength(100)]
public string JobTitle { get; set; }
public ICollection<Project> Projects { get; set; }
}
public class Project : ModelBase
{
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
public string Summary { get; set; }
public int JobId { get; set; }
}
Is there a way to enable cascading deletes in EF Code First without exposing the foreign key on the many side of the relationship?
Yup! Remove JobId and add the following:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Job>().HasMany(j => j.Projects).WithRequired();
}
In the database, this will add a cascading delete in the PK/FK relationship.
(I'm assuming that your ModelBase has an integer Id =)