Given a primary key, is it possible to find all foreign keys in EF Core model? - entity-framework-core

I'm working with a rather large EF core model that has all tables and relationships defined in code that wind up attached to a context object. If I have a primary key, is there a clean/efficient way to get all the dependent columns in the model?
As an example of what I'm working with, this snippet works to find a primary key's name for a given table (the table is known by its type T which is a parameter to the function in which this code lives):
var keyName = context.Model.FindEntityType(typeof (T)).FindPrimaryKey().Properties.Select(x => x.Name).Single();

I found the answer while poking through the properties of they key object. Instead of getting the name, get the object itself, then call these two other methods to get the foreign keys that reference the primary key:
var key = context.Model.FindEntityType(typeof (T)).FindPrimaryKey().Properties.FirstOrDefault();
var foreignkeys = key.GetContainingPrimaryKey().GetReferencingForeignKeys();

Related

How to get foreign key value from not fetched relationship?

Having two entities defining relationship by #ManyToOne and #OneToMany, how can I get foreign key without asking from related object and just by looking at defining tables? How do I get OWNER_ID from Owned by something like owned.getOwnerId() instead of owned.getOwner().getId() and still be able to owned.getOwner()?
Map the field in your entity as a basic mapping allows you to use the foreign key directly. You can keep the object reference mapping as well, but one of the two mappings must then be marked as insertable=false, updatable=false so that JPA knows which mapping controls the field in the event they show different values.

Entity Framework Code first mapping without foreign key

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.

Entity framework code first - association on "polymorphic" columns

I have 3 tables:
1. Invoice
InvoiceID int PRIMARY KEY
2. Order
OrderID int PRIMARY KEY
3. Transaction
TransactionID int PRIMARY KEY
Source int
Category string
On table "Transaction", Source (unfortunately) is behaving as a "polymorphic"(??) foreign key (there must be an actual term for that - sorry for my ignorance) that depending on the Category column it'll contain the ID of Invoice or Order.
However there's no actual foreign key.
Using EF 4.1 code first, anyone has any idea how I would create the proper associations?
Help is appreciated!
Thanks
Solution
Uh... Embarrassment is kicking in... I can just map it same way regardless of any actual DB foreign key.
I was having problems while trying to do that but basically wasn't related to this. I had computation properties that I didn't ask the context to ignore which was generating wrong queries.
You probably should create two nullable FKs instead of weak reference like that.
Uh... Embarrassment is kicking in... I can just map it same way regardless of any actual DB foreign key.
I was having problems while trying to do that but basically wasn't related to this. I had computation properties that I didn't ask the context to ignore which was generating wrong queries.

Setting Entity Framework Fields

I generated a Members table and a MembersType table which has a primary key which links to the Type foreign key in the Members table. The MembersType table is literally just 3 records, so that each Member can be of MemberType 1, 2 or 3.
Now the problem is that when Entity Framework generates the data layer and objects for the Members object, it creates a MemberType object in the Members object, but all I want to be able to do when setting it is:
Members.MemberType = 1;
but because of the above, I have to do this:
MemberTypes = db.MemberTypes.Where(x => x.MemberTypeId == 1).AsQueryable().First()
Is there anyway to stop it from generating an object on foreign keys so I can just set it as an int? Surely this is more quicker and resource efficient than querying the type table everytime too.
You have encountered one of everyone's least favorite features of EFv1. The problem is that everything is an Entity, so you can't get to foreign key values as primitives.
Your code sample shows how it has to be done in EFv1. The best you can do is cache those enum values up front so you don't have to keep getting them from the context. EFv4 does away with this restriction with "FK Properties," which is just a fancy way of saying raw foreign keys you can set directly.

Entity Framework: Model doesn't reflect DB

I'm probably thinking about this all wrong but I have the following db tables:
When I run the EF Wizard in VS2008 I get the following model:
You'll notice that in the EF model shows that the Entity has no field for EntityTypeID or EntityStatusId. Instead it shows it as a navigation property, so the field appears to not be addressable when I instantiate an Entity (pardon the terminology confusion: Entity is a Table/Class in my name space not in the EF namespace). How can I assign an EntityTypeID and StatusTypeID when instantiating an Entity?
Yes, the entity framework hides foreign key ID properties and shows navigation properties instead. There is a lengthy discussion about why it does that, here. The usual means of assigning a reference to another entity is to assign the entity instance, rather than the foreign key ID value, like this:
var foo = new Entity();
var status = (from .... select ...).FirstOrDefault();
foo.StatusCodes = status;
However, it is possible to assign a foreign key ID directly, if you happen to know what it is:
foo.StatusCodesReference = new EntityKey(
"MyEntityContextName.StatusCodesEntitySetName", "StatusCodeId", value);
Obviously, substitute the real values in the above.