I'm just thinking about a foreign key attribute in Entity Framework (using code first approach).
I want to ensure that this foreign key is always set, in other words: It should be required.
Is using the "Required"-attribute/data annotation a clean solution for this? Or should this data annotation be used for user input only?
I don't think you need to have required attribute in the data annotation . If you have declared it as
public int ForeignKeyName{get;set;}
It will take as required by EF. And if it
public int? ForeignKeyName{get;set;}
it will be taken as optional(nullable) by entity framework Conventions . I'm not sure what kind of framework you are using for the web(front end Ex: asp.net mvc). Depend on that you need to think about that input level.
Related
I am creating an EF3 solution for a project.
I have 3 databases, Venue, Catering & Events.
Whenever I run event I get the error:
The entity type 'MenuFoodItem' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'.
I dont know why this is happening as when I run Catering which is where MenuFoodItem class is located it runs and creates the database perfectly fine.
https://github.com/vortexismlg/ThAmCoAssignment
I have no clue what could be causing this considering Catering works fine on its own?
The error you are getting is because EF expects each table to have a Key property, by convention, it looks for properties named ID or TableNAme+ID ( like BookId) to make it Primary Key.
If your table does not have a primary key you just need to decorate your class with [KeyLess] or if you configuring your models by Fluent api just use eb.HasNoKey();
I have two tables:
Requirement
ID (int) PK
ClientID (int)
JobNumber (int)
Comment
ID (int) PK
Job_ID (int)
Comment (varchar)
The tables don't have foreign keys and there's no possibility of adding any. I'm trying to map them in EF. I have classes for each and I'm trying to define the relationship in fluent code to map the Comment.Job_ID to the Requirement.JobNumber. A requirement can have many comments. Requirement has a list of Comments and Comment has a Requirement property.
I have this mapping setup:
modelBuilder.Entity<Comment>().HasRequired(c => c.Requirement)
.WithMany(s => s.Comments)
.HasForeignKey(f => f.Job_ID);
I'm stuck trying to get Comment.Job_ID to map to Requirement.JobNumber.
Any help appreciated.
It's not possible. With Entity Framework the entity that the Comment.Requirement navigation property is refering to is generally identified by the (primary) key property in Requirement, i.e. by ID. There is no mapping option to define that the target property is anything else than the key property - like JobNumber or another non-key property.
I could only imagine that you could "fake" the primary key property in the model to be JobNumber instead of ID (given that JobNumber is unique in the Requirement table):
modelBuilder.Entity<Requirement>().HasKey(r => r.JobNumber);
I don't know if that could have other unwished side effects. (For sure it doesn't work if JobNumber is not unique because EF wouldn't allow to have more than one entity with the same key attached to a context and updates/deletes and so on wouldn't find the correct record in the database.) It feels wrong and hacky to me. I honestly wouldn't even try that, live with the fact that you don't have a real foreign key relationship in the database, forget the navigation properties Requirement.Comments and Comment.Requirement and use manual joins in LINQ to relate the table data/entities as I need them in a given situation.
I have used the Entity Data Model Wizard to generate an EF data model (an edmx with POCO's) based on the Object Catalogue Views in SQL Server, i.e. sys.objects, sys.tables, sys.columns, etc. When I try to access any data through my DbContext's DbSet properties, EF throws a ModelValidationException, complaining that entities don't have keys defined.
I can easily modify the T4 template that generates the entity POCOs to include a dummy property marked with the [Key] attribute, but this seems a bit klunky, as now my entity classes have a 'phantom' property that doesn't belong to them. Choosing a name for the key column is also an issue, but I could do something like generate a GUID for a unique key column name for ever class.
But, isn't there a better, neater way of telling EF I don't need key columns, as this model is strictly read only?
ADDENDUM: If I use the Entity Framework Power Tools - Reverse Engineer Code First tool, it creates a mapping class (derived from EntityTypeConfiguration) for each entity, and where the entity has no define key, it defines one using all the fields in the entity.
I have a method for inserting in database.
I have 1:n relationship between the tables Point (n) and Line (1). Point has foreign key idLine.
However, the class Point in Entity Framework doesn't have the idLine property.
Now, in my method I have object of type Point, as parameter and here I have a problem because I don't know to what to assign the idSection of the new Point object which is inserted in the table.
How to add the idLine property in the Point class?
I'll assume you're using EF4.0, since this is not possible in previous version (EF1.0 does not include foreigh key properties in model).
In your generation wizard you need to make sure that "Include foreign key columns in the model" checkbox is checked when you're generating data model. Otherwise foreign key columns will be omitted when generating data.
If I'm remembering correctly you cannot simply add forign keys to classes that are already generated. You would need to manually edit all the mappings (not impossible, might be little bit troublesome if you are new to EF). Or you can simply remove this class from design area and add it again (making sure appropriate checkbox is checked this time). This might be simpler if you haven't customized generated classes.
add a foreign key in your model like following :-
public int? LineId { get; set; }
public virtual LineId LineId {get; set; } // this for one to one
Using EF 4.0 with the 4.1 upgrade for POCO / code-first.
OK so I have a domain model where type Car has, in a collection, multiple objects of type Part. So a one:many relation.
HasMany(v => v.Parts)
.WithRequired()
.HasForeignKey(v => v.CarId)
.WillCascadeOnDelete();
The problem with this is that it requires me to add a CarId property to my Part type. This is leaking ORM detail into my domain model - which is bad. Marking everything virtual is annoying enough.
Looking at the XML doc comment for the HasForeignKey() method says this:
Configures the relationship to use
foreign key property(s) that are
exposed in the object model. If the
foreign key property(s) are not
exposed in the object model then use
the Map method.
That's great and all. But it introduces a catch-22 situation because if I refactor my Part type by removing the CarId property that I don't want and update my EF model builder to not bother with mapping that property. Then as you can imagine it means I cannot then call HasKey() for defining the composite key, ala:
HasKey(v => new { v.CarId, v.PartId });
HasKey() doesn't appear to support defining the keys based upon non-Property lambdas.
What is the solution here?
If you absolutely don't like to have foreign key properties in your model you could remove the convention to detect FK properties to avoid that EF marks properties automatically as FK properties ...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions
.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>();
}
... and then simply don't specify the FK property in your mapping:
HasMany(v => v.Parts)
.WithRequired()
.WillCascadeOnDelete();
You still need CarId in your model because it is part of the primary key, but this way it doesn't act anymore as foreign key property.
Just an idea, I am not sure if it works.
Well, what about adding a new key field to CarParts table like CarPartId, so you would not need the composite key. (Composite Key support is not that great when working with ORMs.)