The value of 'X' is unknown when attempting to save changes - entity-framework

The value of 'X' is unknown when attempting to save changes. This is because the property is also part of a foreign key for which the principal entity in the relationship is not known primary key.
The field it is complaining about is not a foreign key, but it is part of a composite primary key. Changing the value of this field from 0 to for example 1 solves this problem. The key is defined by the [Key] attribute:
[Key]
public int ClientId { get; set; }
[Key]
public int SubClientId { get; set; }
What is going on?

Related

EF Core: one-to-one 'satellite' table needs its own key?

Here's my scenario:
public class Main
{
public Guid Id { get; set; }
public string Something { get; set; }
public MoreDetail OptionalDetail { get; set; }
}
public class MoreDetail
{
public Guid MainId { get; set; }
public Main Main { get; set; }
public string MoreInfo { get; set; }
}
// model building code:
mainBuilder.HasOne(m => m.OptionalDetail).WithOne(d => d.Main).IsRequired(false);
Intended:
MoreDetail is an optional 'child' table of Main
The primary key would be MainId; it doesn't need its own ID
Actual:
The entity type 'Main' requires a key to be defined.
Attempted:
Adding moreDetailBuilder.HasKey(d => d.MainId). Yields the same error.
Adding .HasForeignKey<MoreDetail>(d => d.MainId) to Main model builder code. Gives The foreign key {'MainId'} on entity type 'MoreDetail' cannot be marked as optional because it does not contain any property of a nullable type. Any foreign key can be marked as required, but only foreign keys with at least one property of a nullable type and which is not part of primary key can be marked as optional..
Using .IsRequired(true) instead. Key setup and inserting records works fine.. but at query time, EF Core generates an INNER JOIN which means nothing is returned if there are no records. :'(
The official docs example show the child/satellite table having its own primary key. It just seems unnecessary; the data is completely identified by its foreign key, isn't it?

How do I make this Code First relationship not required

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.

Name generated for foreign key overwrites existing column name

I am using Code First EF v6.0. I have a table MyTable, which should have 3 columns:
Id (the private key), Name and OtherTable_Name (the foreign key).
[Key]
public int Id { get; set; }
[Index(IsUnique = true)]
[MaxLength(400)]
public string Name { get; private set; }
public virtual OtherTable ARandomStringName { get; set; }
I was getting a weird bug where Name was populated with the value of OtherTable_Name, and no foreign key was generated.
I renamed the private key of OtherTable to OtherTableName. Now I get a database table which has Id, Name, and OtherTable_OtherTableName.
This solves my immediate problem - missing foreign key, incorrect Name value - but I don't understand why it was happening in the first place. (And I'd rather be able to refer to the field sensibly as OtherTable.Name, not OtherTable.OtherTableName.)
When does EF prefix foreign key column names with OtherTable_, and when does it not? This bug has not happened on any pair of tables where both have "Id" as the private key column - is it anything to do with the field being the private key in one table and not the other? What should I be doing to avoid this kind of bug happening elsewhere?
You can use DataAnnotations to override EF conventions. Make sure you have a reference to
using System.ComponentModel.DataAnnotations
then simply add the ForeignKey attribute to your NavigationProperty
public int OtherTableId { get; set; }
[ForeignKey("OtherTableId")]
public virtual OtherTable OtherTableItem { get; set; }

EF 6.1 Code First - the number of columns specified must match the number of primary key columns

I am running into the following error while trying to migrate a database in Entity Framework.
The specified association foreign key columns 'question_set_id' are invalid. The number of columns specified must match the number of primary key columns.
I dropped the original primary key QuestionSetId and created a composite key relationship. The columns in the composite key relationship also map to foreign keys. I'm not sure what the issue is.
Here is the associated entity.
public class QuestionSet
{
[Key, Column(Order = 1)]
public long TitleId { get; set; }
[ForeignKey("TitleId")]
public virtual Title Title { get; set; }
[Key, Column(Order = 0)]
public long ReviewCycleId { get; set; }
[ForeignKey("ReviewCycleId")]
public virtual ReviewCycle ReviewCycle { get; set; }
public virtual List<Question> Questions { get; set; }
}
The DbContext has:
modelBuilder.Entity<QuestionSet>()
.HasMany(c => c.Questions)
.WithMany(c => c.QuestionSets)
.Map(x => x.ToTable("QUESTION_SET_QUESTION")
.MapLeftKey("question_set_id")
.MapRightKey("question_id"))
;
The QuestionSet has two keys, but the MapLeftKey of QuestionSet only spefified one key.
MapLeftKey("question_set_id")
Replace it with something like this:
MapLeftKey(new []{ "question_set_review_cycle_id", "question_set_title_id" })
The first key is ReviewCycleId (Column's Order 0), the second key is TitleId (Column's Order 1).
It should fix the problem, unless the Question also has two keys.

Fluent mapping for EF when foreign key not suffixed with ID

How to implement fluent mapping for the below scenario, I tried but it ends in vain.
I have two table Product and State, Product have column name State which hold StateCode like "WA", "NJ" etc which of string type. So i need to populate the State column into StateCode and the related State object into State property of the product entity.
Below is the classes i am using. I don't want to change the columns of table
public class Product
{
public int ID { get; set; }
public State State { get; set; }
public string StateCode { get; set; }
public string Description { get; set; }
}
public class State
{
public int Id { get; set; }
public string Code{get;set;}
public string Description{get;set;}
}
I tried the below mapping for Product
this.Property(t => t.StateCode).HasColumnName("State");
HasRequired(t => t.State).WithMany().HasForeignKey(t => t.StateCode);
No, currently it's not possible to have a Foreign Key column that refers to non PK in entity framework. Check this feature suggestion.
If you really want to have that feature, you need to have custom Seed that execute.
alter table Products add constraint FK_Products_States foreign key(State) references States(Code)
But you will not be able to populate State object. Putting public State State { get; set; } property will automatically create a Foreign Key column State_ID that refers to States::ID.
Otherwise you need to change the StateCode to be StateId (integer) that refers to State::Id.
The type of ForeignKey and PrimaryKey of referenced table must be the same. So you need to set State class Id property type to string. In EF you can only use foreig keys pointing to primary keys.