I have two tables named as Profile and ProfileHistory.
Each record in ProfileHistory has to belong to a profile in Profile table, so there is a foreign key relation between two tables. Besides, in ProfileHistory table, there is a column named as ManagerId which also relates to Profile table with foreign key relation.
Profile table structure
Id int primary key
....
....
ProfileHistory table structure
Id int primary key
ProfileId int foreign key to Profile table
ManagerId int foreign key to Profile table
....
My question is:
Since currently I only know this, I am creating my entity model from database.
Model and therefore entity classes are created with navigation properties in
ProfileHistory entity like following:
public virtual Profile Profile { get; set; }
public virtual Profile Profile1 { get; set; }
It is so confusing. Because it is not clear which navigation property for which relation.
Even it is worse if I have more relations between two tables. navigation property names are becoming Profile, Profile1, Profile2, etc.
I was expecting to have the name of the navigation properties related with its foreign key relations.
How can I make my navigation property names something that related to its foreign key relation, in my case "from Profile1 to ProfileManager" ?
Thank in advance for your kind helps.
Muharrem
You can always rename the properties in model diagram. The name can be found in Properties window when you click on a navigation property.
I haven't tested it, but you can map a property to a column using an attribute:
[Column(“BlogDescription", TypeName="ntext")]
public virtual Profile Profile { get; set; }
[Column("Profile1", TypeName="int")]
public virtual Profile ProfileManager { get; set; }
Change the type and the name of the column as it is in the database.
The way I usually solve this is to add properties through partial classes that better represent what I'm after. This way if I need to delete the entity from the diagram and re-add it, I don't lose any renamed columns from the model.
The downside to this is that you need to remember that you cannot use them in Queries because EF won't know how to translate it into a SQL query. But if you've already got your Profile object, it's a lot easier to access myProfile.Manager than myProfile.Profile1.
So, for example, if EF created this for you:
public partial class ProfileHistory
{
public virtual Profile Profile { get; set; }
public virtual Profile Profile1 { get; set; }
}
I would end up creating a partial class like this to re-map the columns:
public partial class ProfileHistory
{
public Profile Manager
{
get
{
return this.Profile1;
}
set
{
this.Profile1 = value;
}
}
}
I did face the same problem some time ago. Well, it is even bigger then just confusing names. If you have navigation properties to another table, like Profile, Profile1, Profile2, next you delete/edit the corresponding foreign keys you may end up having those mixed. And if you used EntitySQL to query data you'll end up having bugs because of incorrect data retrieved/wrong table join conditions...
What I did was changing the t4 template and modified the way properties are generated. When property code text is being written you have the information about association and foreign key related to it. Foreign key names are unique in database and I named those with following pattern
FK_[Table]_[Meaning]
...
FK_ProfileHistory_InitialProfile
FK_ProfileHistory_UpdatedProfile
Next, having this information, I named the properties with the [Meaning] part of the foreign key name.
Related
I'm using the database-first approach while setting my first steps in Entity Framework. In my SQL Server database I have two tables, Location and Area.
Both have an Id column and the Location table already has an AreadId property. I would like to use this property for creating a one-to-many association between both tables (many Location entries for one Area entry), so I have created the following in my EDMX diagram using the EDMX-designer:
In the automatically generated Location.cs file, it looks as follows:
public partial class Location
{
...
public int AreaId { get; set; }
...
public virtual Area Area { get; set; }
}
I would like to use the already existing property Location.AreaId as the foreign key. How can I do that, using EDMX-designer?
Please keep in mind that I can modify the EDMX diagram, but not the automatically generated Location.cs file.
Thanks in advance
In learning the code-first EntityFramework methodology, I don't understand why you need "duplicate" references between two data sets, i.e. a Navigation Property as well as an explicitly defined foreign key.
For example, an "Enrollment" has a one-to-one relationship with a "Course" and a "Student". In the student's model class, you define a navigation property like so:
public virtual ICollection<Enrollment> Enrollments { get; set; }
This will create a column for foreign keys to Student in the Enrollments table if you do a migration.
But in the "Enrollment" class, you also have a property representing the Student's foreign key like so:
public int StudentID { get; set; }
So my question is: what is the purpose of defining this foreign-key relationship on both ends? I have seen it done where only the Navigation Property is defined on one end, and also where the relationship is only defined on the other end. What is the reason for both?
The navigation property allows you to access the collection of referenced entities when you query the entity.
The single ID property is the reference to the column that actually holds the value of the foreign key reference.
I am using EF to access a SQL DB. For the sake of this example Lets assume I have a Users Table, a User Comments Table (comments made by users) and a Liked comments table (comments a user marked like on them) when the Context is generated I get in the User.cs file the following ICollections:
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Comment> Comments1 { get; set; }
How can I know which is which? Why does EF not add the foreign key table name to the column?
I have several of these issues.
in the edmx designer, click on the navigation property ("Comments" or "Comments1") and press F4 to show it's properties. The properties panel will display the foreign key name which will give you enough info to identify which is which.
The following are two partial tables in which I am trying to define a foreign key relationship.
public class Form
{
[Key, Column("FormID")]
public System.Guid FormGUID { get; set; }
[Column("PatGUID")]
public Nullable<System.Guid> PatientGUID { get; set; }
}
public class Patient
{
[Column("PatGUID")]
public System.Guid PatientGUID { get; set; }
[Key, Column("PatID")]
public int PatientID { get; set; }
}
I've eliminated all but the relevant information, fields, navigations, etc. for this example; hopefully not too much.
We have a table Form, with a FK of PatGUID to a Patient table with field PatGUID.
The Patient table has a PatID int KEY field.
We have requirements to rename our fields for our code first entity models; the relevant fields in this example needing changed is PatGUID being changed to PatientGUID.
The difficulty I am having is trying to define this foreign key using either annotations or fluent.
So the end result I need is:
Primary Key Table: Patient, Field: PatGUID (renamed PatientGUID)
Foreign Key Table: Form, Field: PatGUID (renamed PatientGUID)
This doesn’t seem like it should pose a large problem but with the combination of Patient.PatGUID not being the primary key and the PatGUID fields being renamed to PatientGUID has not enabled the WCF Data Service to properly create a reference with a proper reference thus a proper select/join of:
SELECT … FROM [dbo].[Form] AS [Extent1]
INNER JOIN [dbo].[Patient] AS [Extent2] ON [Extent1].[PatGUID] = [Extent2].[PatGUID]
EF doesn't yet support relationships where the principal's key is not the primary key but some other column with a unique key constraint. It is on the feature request list but neither implemented nor on the road map for the next release (EF 6). If it gets implemented at all (in EF 7 maybe) expect to wait a year or more until it's ready for production.
In your particular model EF doesn't recognize any relationship between Form and Patient at all because Patient.PatientID is marked as [Key], not Patient.PatientGUID, and EF treats Form.PatientGUID as an ordinary scalar property, not as an FK to Patient.
In theory you could fake Patient.PatientGUID as the [Key] property in the model although it is not the primary key in the database if you don't create the model from the database or the database from a code-first model, that is, if you map between model and (existing) database manually. But I am not sure if this wouldn't cause subtle problems anywhere else.
The alternative is to write manual join statements in LINQ if you want to fetch Patients and related Forms. You can then join two entities using arbitrary properties, not only key properties. This is, in my opinion, the cleaner and less "tricky" approach. However, the downside is that you won't have navigation properties - references or collections - between Patient and Form and you can't use features like eager loading (Include), lazy loading or comfortable "dotted path syntax" (like Form.Patient.SomePatientProperty, etc.) in your LINQ queries.
I have an Events table whose goal is to store actions done by web site users. An action basically alters or create a new row in a table X. This will allow me to store an history of all actions done by a user. As such, Events contains:
a primary key column
a text to describe the event (ex: "posted a comment")
a discrimator column if needed
a foreign key column to another table A
a foreign key column to another table B
....
a foreign key column to another table N
A row in the Events table will have only one of the foreign key columns set, all others will be null (so they are all nullable). The table behaves like an indirection table to the actual table concerned by the event. I don't know if a discriminator is needed since all the information is contained in the foreign key columns.
Tables A to N can be anything. Their domain model class can have a common interface if necessary (IEventRecordable).
My question is:
Is a mapping possible between the Events table and an Event class? Is it especially feasible with fluent nhibernate? Can it be done without having to create many derived classes of Event (I don't want to create so many empty subclasses)? The Event class would ideally be as follows:
public class Event
{
public virtual int Id { get; set; }
public virtual IEventRecordable ActualEvent { get; set; }
public virtual string EventDescription { get; set; }
DateTime EventDateTime { get; set; }
}
Many classes among the domain model classes could implement IEventRecordable (which is mainly an empty interface). It could be the User table or a BlogComment table...
Thanks
If you forget about the multiple foreign key columns, you can make this an <any> mapping.