I have a problem with Entity Framework.
If I add a Datatable from my DB over my Entity Data Model and this model has 2 Foreign Keys to the same table, the names of this Foreign Keys becomes confusing. Can I make any configurations to set this Foreign Key names beforehand?
I dont want to make any changes after the model is generated.
Here a example from my model
public partial class PERSON
{
public System.Guid ID { get; set; }
public string NAME { get; set; }
public System.Guid TABLE_REGION_FK { get; set; }
public virtual TABLE_REGION TABLE_REGION { get; set; } // -> property name should be TABLE_REGION_PARENT
public virtual TABLE_REGION TABLE_REGION1 { get; set; } // -> property name should be TABLE_REGION_CHIELD
}
Related
I'm trying add migration using EF core 2 code first method. The issue is that, the entities with foreign key relationship are created with a foreign key id suffixed with '1' at the end and a redundant column with the same name but without the 1 at the end which is not a foreign key.
Examples are my 2 classes, Store and StoreVisit as shown below:
Store
[Table("Store")]
public class Store
{
public Store()
{
StoreVisits = new HashSet<StoreVisit>();
}
[Key]
public int StoreId { get; set; }
[StringLength(30)]
public string ShopName { get; set; }
[StringLength(50)]
public string ShopKeeper { get; set; }
public string ContactNo { get; set; }
[StringLength(70)]
public string Address { get; set; }
[StringLength(20)]
public string Street { get; set; }
[StringLength(50)]
public string City { get; set; }
public IEnumerable<StoreVisit> StoreVisits { get; set; }
}
Store Visit
[Table("StoreVisit")]
public class StoreVisit
{
[Key]
public int StoreVisitId { get; set; }
[StringLength(50)]
public string Location { get; set; }
[StringLength(50)]
public string Notes { get; set; }
[DataType(DataType.Time)]
public DateTime StartTime { get; set; }
[DataType(DataType.Time)]
public DateTime EndTime { get; set; }
public Store Store { get; set; }
}
The Visit class is created in the database with the column shown in the image below:
As you can see, the StoreVisit table has columns "StoreId1" which is the actual foreign key and "StoreId" which is not a foreign key.
I have even configured the relationship with Fluent API as below:
modelBuilder.Entity<Store>()
.HasMany(c => c.StoreVisits)
.WithOne(e => e.Store)
.IsRequired();
Can someone help.
Note that Entity Framework Core is smart enough to detect relationships among your classes which will be turned into database tables with relationships if you use its conventions. So this is redundant to use annotations like [Key] above StoreId property.
Second thing, As an advice, try to use simple and clean names for classes or properties as they can be potentially similar to those automatically created by EF. For example, in your case I prefer to avoid using store inside StoreVisit class name again (e.g in case of many to many relationship, derived table is named StoreVisit like one that you employed just without 's', Although your case is one to many),
And Final tip is the reason for appearing redundant StoreId column. Actually, In your case, this is not necessary to use Fluent API as EF can detect the relationship. In addition, you've written wrong configuration for modelBuilder. So remove it and let EF to generate it (unless you plan to have fully defined relationship to consume its advantages in your code).
The StoreId is one that you told EF to generate it (as required)
in modelBuilder.
The StoreId1 is EF Auto generated column (Foreign Key) based on one
to many relationship. '1' is appended in order to avoid column name duplication.
A foreign key needs to be defined on the class.
[Table("StoreVisit")]
public class StoreVisit
{
[Key]
public int StoreVisitId { get; set; }
public int StoreId { get; set; }
[StringLength(50)]
public string Location { get; set; }
[StringLength(50)]
public string Notes { get; set; }
[DataType(DataType.Time)]
public DateTime StartTime { get; set; }
[DataType(DataType.Time)]
public DateTime EndTime { get; set; }
public Store Store { get; set; }
}
It also would hurt to add the foreign key reference to the Fluent API.
modelBuilder.Entity<Store>()
.HasMany(c => c.StoreVisits)
.WithOne(e => e.Store)
.HasForeignKey(e => e.StoreId)
.IsRequired();
I am new to entity framework and I am using code first approach to create entities using TPT inheritance.
My requirement is to create the entities as per the attached diagram where ID is PK for Customers table and FK for the AddressDetails and ContactDetails table. Based on the keys I also need to create the association and navigation properties for the entities. Table Diagram
In my code I have created entities as
public class Customer
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int ZipCode { get; set; }
public virtual ContactDetails ContactDetails { get; set; }
public virtual AddressDetails AddressDetails { get; set; }
}
[Table("ContactDetails")]
public class ContactDetails: Customer
{
public string MobileNo { get; set; }
public string EmailId { get; set; }
}
[Table("AddressDetails")]
public class AddressDetails: Customer
{
public string BillingAddress { get; set; }
public string DeliveryAddress { get; set; }
}
My question is, have I created the association and navigation properties correctly or do I need to add them in the ContactDetails and AddressDetails class as well? Also, when I run the code the entities are getting created in the database but for the Customer table there are 2 additional columns created as AddressDetails_Id(FK,int,null) and ContactDetails_Id(FK,int,null). I think they are created because of the navigation property but I do not need these columns in the database to be created. Also the values are always null in these two columns.
Any help would be appreciated. Thanks in advance.
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; }
}
I have a model like this:
public class Entity
{
[Key, Required]
public virtual long EntityId { get; set; }
[Required]
public virtual string Name { get; set; }
public virtual long? ParentEntityId { get; set; }
}
and this is my table:
create table Entities(
EntityId bigint not null identity(1, 1),
Name nvarchar(64) not null,
ParentEntityId bigint null
)
ParentEntityId is a foreign key to EntityId.
When I try to create a Entity entity this is the exception I get:
Invalid column name 'ParentEntity_EntityId'.
I don't know why EF is picking that convention for that particular column, but if I do this:
[Column("TryPickThisName")]
public virtual int? ParentEntityId { get; set; }
The same error shows up with "TryPickThisName" column name. And finally if I write the column name correctly or remove the attribute it will show the original error message.
Did you leave part of your model out?
I think what is happening is you're wanting to create a self referencing table, with Entity optionally referring to itself if it has a ParentEntity.
What's happening is EF is creating the ParentEntity_EntityId because you didn't explicitly map the FK property to the navigation property. Adding a ForeignKey data annotation will correct this.
public class Entity
{
[Key, Required]
public virtual long EntityId { get; set; }
[Required]
public virtual string Name { get; set; }
[ForeignKey("ParentEntity")]
public virtual long? ParentEntityId { get; set; }
public virtual Entity ParentEntity { get; set; }
}
Creates this database:
We have the following set of objects.
public class Form
{
public int FormId { get; set; }
public DateTime DateCreatedOn { get; set; }
public string Status { get; set; }
}
// This is using TPT inheritance from Form
[Table("FormA")]
public class FormA : Form
{
public string ExtraInfoA { get; set; }
public virtual ICollection<Child> Children
}
// This is using TPT inheritance from Form
[Table("FormB")]
public class FormB : Form
{
public string ExtraInfoB { get; set; }
public virtual ICollection<Adult> Adults
}
public class Person
{
public int PersonId { get; set; }
public int FormId
public DateTime DateOfBirth { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
// This is using TPH inheritance from Person
public class Adult : Person
{
public int HowManyCars { get; set; }
public string NationalInsuranceNo { get; set; }
[ForeignKey("FormId")]
public virtual FormB FormB { get; set; }
}
// This is using TPH inheritance from Person
public class Child : Person
{
public int HowManyToys { get; set; }
public string SchoolName { get; set; }
[ForeignKey("FormId")]
public virtual FormA FormA { get; set; }
}
This creates 3 tables for the forms Form, FormA, and FormB, all with the appropriate fields in them. It also creates 1 table for Person.
The problem is When we rely on the convention and don't specify the ForeignKey attribute the Person table contains 2 additional foreign key columns.
However when we do specify the ForeignKey attribute (as in the code above) we get the following error message.
`The foreign key component 'FormId' is not a declared property on type 'Child'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.`
FormId is definitely a property of Child so I'm not sure what is going wrong.
Our real world situation is a lot more complicated that the situation above so I'd like to get it right now rather tham have multiple foreign keys.
Any help is very much appreciated.
You cannot define foreign key in the parent entity and navigation property in the child entity. They must both be defined in the same entity. What you are trying to do is even not valid in the database because you cannot have conditional foreign key constraint on the column - constraints to both FormA and FormB will be applied for every record and you will never be able to insert any record (because it would always violate constraint to FormA or FormB).
In short: You need either single navigation property in parent or separate foreign key for every child.