I have a MasterUserApprovalOfficial entity with two foreign keys, MasterUserId and SoftwareSystemId. EF 7 is smart enough to figure out that these two properties are foreign keys.Here is my MasterUserApprovalOfficial class
public class MasterUserApprovalOfficial
{
public int MasterUserApprovalOfficialId { get; set; }
public int MasterUserId { get; set; }
public MasterUser MasterUser { get; set; }
public int SofwareSystemId { get; set; }
public SoftwareSystem SoftwareSystem { get; set; }
public bool Active { get; set; }
public DateTime CreateDate { get; set; }
public MasterUserApprovalOfficial()
{
CreateDate = DateTime.Now;
}
}
If I look at the table that was created the MasterUserId column was created and named as expected, the SoftwareSystemId column however is created as SoftwareSystemSoftwareSystemId (The name of the class appended to the name of the primary key)
Is there any reason for this?
public int SofwareSystemId { get; set; }
read that property again. there's a t missing :)
the second answer is also right, you don't need properties for the foreign key. A member of the class is enough
Use the ForeignKey and Column attributes to fix this:
[ForeignKey("SoftwareSystem"),Column("SoftwareSystemId")]
public int SoftwareSystemId { get; set; }
By default the foreign key will be added with "Id" behind it, but because you already have a property with that name (and EF doesn't recognize it's the foreignkey apparantly) it gets changed into SoftwareSystemSoftwareSystemId.
Related
I have a Stick class that has a relationship with the InventoryItem class. I have a code that has a bunch of sticks. I loop through the sticks to create each individual Stick and assign the InventoryItem to that stick.
However when I try to save the DbContext, I get an error of
SqlException for Identity Column for table InventoryItems.
I don't understand why, since the InventoryItem is already create before all of this. All I did was passing the InventoryItem back and forth from the view model and the view.
Please see the image below. If I remove the highlighted line of code, then DbContext will be able to save and my InventoryItem for the sticks will be Null.
Please see more code references below and advise. If you need more info please let me know. Thanks.
Error Image
Stick Class:
public class Stick
{
public int Id { get; set; }
public InventoryItem InventoryItem { get; set; }
}
InventoryItem Class:
public class InventoryItem
{
public int Id { get; set; }
public string Name { get; set; }
public string PartNumber { get; set; }
public double Length { get; set; }
public double GetLengthInInches => Math.Round(Length / 25.4, 0);
}
ViewModel
public class OptimizationViewModel
{
public InventoryItem InventoryItem { get; set; }
public IList<Cut> TempInstanceCuts { get; set; }
public IList<Stick> TempInstanceSticks { get; set; }
public double[] Percents { get; set; }
public int CutQuantity { get; set; }
public double CutLength { get; set; }
public int stickCount { get; set; }
public OptimizationViewModel()
{
TempInstanceCuts = new List<Cut>();
TempInstanceSticks = new List<Stick>();
}
}
It looks like you manually set the Id value for InventoryItem entity. You should not do that as it is auto-generated. Just ignore it when you create this entity.
This is a simple omission: if you have an INT IDENTITY column in your table, you need to add a [DatabaseGenerated(DatabaseGeneratedOption.Identity)] annotation on the key column in your model class:
public class InventoryItem
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string PartNumber { get; set; }
public double Length { get; set; }
public double GetLengthInInches => Math.Round(Length / 25.4, 0);
}
And if the Id of Stick is also an identity column, do the same for that column, too, in your model class.
That annotation simply tells EF that this column is an identity column which is handled by SQL Server and that EF should ignore any value you might have assigned to it, and not include that column into an INSERT statement.
Update #2: it appears that EF Core has a new default behavior to automatically assume any non-composite primary key is handled by the database as a "generated property". Thanks to #LazZiya for that pointer: Generated value on Add
If you want to set the primary key value of InventoryItem model manually, you need to use [DatabaseGenerated(DatabaseGeneratedOption.None)] attribute.
public class InventoryItem
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
//other properties
}
Refer to https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations#no-value-generation-1
So I took the time to read some of these and decide to rewrite my classes. I found what really helpful was I need to add an extra property like the ForeignKeyID which did help me work with related data. such as:
public class Stick
{
public int Id { get; set; }
public InventoryItem InventoryItem { get; set; }
public int ForeignKeyInventoryItemID { get; set; }
}
Thanks for the documentations.
So I try to create some ASP.NET project with EF Core.
I want to set propert of one entity as primary key and foreign key to another entity. The relationship is 0..1 - 1. I use DataAnnotations:
public class OfficeAssignment
{
[Key, ForeignKey("InstructorID")]
public int InstructorID { get; set; }
public Instructor Instructor { get; set; }
public string Location { get; set; }
}
But I keep getting column InstructorID as PK and InstructorID1 as FK... Any ideas, why EF behaves like that and how can I achieve my goal?
You should follow convention over configuration as much as you can. An OfficeAssignment entity should have an OfficeAssignmentId PK, like this:
public class OfficeAssignment
{
public int OfficeAssignmentId { get; set; }
//Notice that Id does not have an uppercase D
public int InstructorId { get; set; }
public string Location { get; set; }
public Instructor Instructor { get; set; }
}
However, if you don't want to follow normal conventions, the name of the property that goes in the ForeignKey attribute is the opposite of where it's declared:
public class OfficeAssignment
{
[Key, ForeignKey("Instructor")]
public int InstructorId { get; set; }
public string Location { get; set; }
public Instructor Instructor { get; set; }
}
And, if you want to keep it compile-time safe:
public class OfficeAssignment
{
[Key, ForeignKey(nameof(Instructor))]
public int InstructorId { get; set; }
public string Location { get; set; }
public Instructor Instructor { get; set; }
}
It's enough to set primary key attribute([Key]) in the OfficeAssignment class and in Instructor class we need to set such attribute:
[InverseProperty("Instructor")]
on collection of CourseAssignments. That will work as desired.
I don't know if anyone face this issue or it's just something else.
I am using a EF code-first architecture.
Here is my first class :
public class PerformanceSurchargeGeneralSettings : FullAuditedEntity
{
public int PerformanceID { get; set; }
public Performance Performance { get; set; }
public int SurchargeId { get; set; }
public Surcharges Surcharge { get; set; }
}
And here is the second class:
public class Surcharges : FullAuditedEntity
{
public string Name { get; set; }
public ICollection<PerformanceSurchargeGeneralSettings> PerformanceSurchargeGeneralSettings{ get; set; }
}
Everything works fine, I can add migration, update my database but if I go to table and check for foreign key reference, I can't see primary key table. See this screenshot here:
I am not able to find newly added table that is Surcharge in the dropdown of primary key table.
And if I execute SP_help for this table, I can find all foreign keys, see the screenshot:
I don't understand where exactly the issue is ...
H,
Change your classes as below;
[Table("PerformanceSurchargeGeneralSettings")]
public class PerformanceSurchargeGeneralSetting : FullAuditedEntity
{
[ForeignKey("PerformanceId")]
public virtual Performance Performance { get; set; }
public int PerformanceId { get; set; }
[ForeignKey("SurchargeId")]
public virtual Surcharge Surcharge { get; set; }
public int SurchargeId { get; set; }
}
[Table("Surcharges")]
public class Surcharge : FullAuditedEntity
{
[MaxLength(128)]
public string Name { get; set; }
public virtual ICollection<PerformanceSurchargeGeneralSetting> PerformanceSurchargeGeneralSettings{ get; set; }
}
My advises
Use singular names for classes. Surcharges => Surcharge.
Give MaxLength to string properties.
Use the same case for all Id fields. PerformanceID => PerformanceId. (like you did for SurchageId).
Add virtual key when you want to load data with lazy loading.
I am new to Entity Framework so I don't know much about it. Currently I am working on My College Project, in that Project I came across a problem where I have two foreign keys refers to the Same column in another table. how can I handle this situation.
Is it necessary to create Navigation Property for Every Foreign key. And if I create another Navigaton property for ContactId then it is necessary to create another Navigation Property in User class like:
public virtual ICollection<BlockedUser> SomePropertyName { get; set; }
please tell me the best way to overcome this problem. I am using Entity Framework 6.
Here are My Model Classes:
public class BlockedUser
{
// User Foreign Key
public int UserId { get; set; } // Composite Primary Key
// User Foreign key
public int ContactId { get; set; } // Composite Primary Key
// User Navigation Property
public virtual User User { get; set; }
}
public class User
{
public int UserId { get; set; } // Primary key
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
// BlockedUser Navigation Property
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
}
Is it necessary to create Navigation Property for Every Foreign key?
Yes, or more precisely: You need at least one navigation property for every relationship. "At least one" means that you can decide which of the two entities you want to add the navigation property to. It normally depends on the most common use cases in your application if you often want to navigate from entity A to entity B or the other way around. If you want, you can add the navigation properties to both entities but you don't need to.
In your model you apparently have two (one-to-many) relationships. If you want to expose navigation properties in both entities you would need four navigation property and - important! - you have to define which navigation properties form a pair for a relationship (see the [InverseProperty] attribute in the following code snippet).
With data annotations it would like this:
public class BlockedUser
{
[Key, ForeignKey("User"), Column(Order = 1)]
public int UserId { get; set; }
[Key, ForeignKey("Contact"), Column(Order = 2)]
public int ContactId { get; set; }
[InverseProperty("BlockedUsers")]
public virtual User User { get; set; }
[InverseProperty("BlockedContacts")]
public virtual User Contact { get; set; }
}
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
public virtual ICollection<BlockedUser> BlockedContacts { get; set; }
}
If you don't want the BlockedContacts collection you can probably just remove it and the [InverseProperty("BlockedContacts")] attribute from the Contact navigation property as well.
You could use attribute ForeignKey to solve your problem. ForeignKey is used to pair navigation property and foreign key property.There is no difference between FK data annotation with Foreign Key property and FK with Navigation Properties. However, the following code will create two foreign keys with different name.
public class BlockedUser
{
// User Foreign Key
[ForeignKey("UserId")]
public int UserId { get; set; } // Composite Primary Key
// User Foreign key
[ForeignKey("BlockedUser_User")]
public int ContactId { get; set; } // Composite Primary Key
// User Navigation Property
public virtual User User { get; set; }
}
public class User
{
public int UserId { get; set; } // Primary key
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
// BlockedUser Navigation Property
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
}
I'm attempting to set fields in a database using the mvc3 method. When I run the program I get a
System.Data.Edm.EdmEntityType: : EntityType 'CarModel' has no key defined. Define the key for this EntityType.
my model looks like this
public class CarModel
{
public string VIN { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public string Year { get; set; }
public string Color { get; set; }
public string Mileage { get; set; }
public string Description { get; set; }
}
I've seen where people add a ID, but the database doesnt have an ID property. And when I attempt to add [Key] above the VIN, which is the primary key in the database. It gives an red squiggly error under key.
It seems im missing some reference.
The reference you're missing is probably System.ComponentModel.DataAnnotations; is this not added for you if you type Ctrl-. with the cursor next to [Key]?
Entity framework requires each entity to have a Primary Key defined. If you just want to remove the error then add this:
[Key]
public int id { get; set; }
and
public CarModel()
{
id = 1;
}