I have two tables
Normally, I would set them up as:
Classes
--------------
ClassID int autoinc
ClassName string
Session
--------------
SessionID int autoinc
SessionName string
SessionStart date
SessionEnd date
ClassID int FK
I would then query the sessiontable and join the classes table on classid.
In setting this up using CoreData do I still need the ClassID? I see that I can setup a relationship, but it doesn't seem to link to a specific column... only a table..
Your thinking is a a little database-oriented, which is no bad thing, but a Core Data schema isn't a relational database schema. You need to think in terms of objects, not tables and columns. You have two entities, not two tables.
The framework itself handles generating unique identifiers for each object. This identifier is really just an implementation detail. Create the objects, define the relationships, and Core Data will handle the rest, including creating bridge tables to handle many-to-many relationships.
Related
I'm having a hard time finding the exact answer to this question, so my apologies if this is redundant.
So I have 3 tables defined such that:
Person :PersonId, FirstName, LastName
Company: CompanyId, CompanyName
Order: OrderId, PersonId, CompanyId
On the Order table, there is a foreign key defined on the PersonId and CompanyId columns, thus, my Order entity class generated by EF has a navigation properties of type Person (not PersonId) and Company.
So, to insert into the Order table, I first need to query the person and company tables to get the person and company entities. Then I can construct the Order object using the Person and Company entities and save it to the db.
In my scenario, I am being passed a PersonId and CompanyId.
In classic SQL I would just do INSERT INTO Order Set (CompanyId, PersonId) - 1 database call. But with EF, I have to do 3 db calls. This seems like overkill.
Is there any way around this?
PS - I'm using EF 6. I know I could generate an expression and make it single call..but that would still yield two subselects.
You can just include foreign key properties in addition to the navigation properties and then set them using the ids you have. If you do this will not have to go to the database to get related entities for just a sake of setting the relationship.
I am struggling with the way entity framework handles join tables, specifically because entity framework requires that a join table has a composite key composed of the primary keys on the two related entities I want the hold the relationship for. The problem here is that I need to hold a relationship to the relationship so to speak.
This may be a problem with my database design or equally due to my lack of understanding with EF. It is probably best illustrated through example (see below);
I have three tables each with a primary key:-
Table : DispatchChannel
{ *DispatchChannelID integer }
Table : Format
{ *FormatID integer }
Table : EventType
{ *EventTypeID integer }
The relationship between EventTypes and DispatchChannels is held in EventTypeDispatchChannels (see below) since this only contains a composite key it is not pulled through into our model and entity framework takes care of maintaining the relationship.
Table : EventTypeDispatchChannels
{ EventTypeID integer, DispatchChannelID integer
}
My problem now arises because for each combination of EventTypeID and DispatchChannelID I want to hold a list of available formats, this would be easy if my EventTypeDispatchChannels table had a primary key therefore my other join table would look like this;
Table : EventTypeDispatchChannelFormats
{ EventTypeDispatchChannelID integer, FormatID integer
}
The absence of a primary key on EventTypeDispatchChannels is where I am struggling to make this work, however if I had the key then entity framework no longer sees this as a linked entity.
I'm relatively new to C# so apologies if I have not explained this so well, but any advice would be appreciated.
The moment you want to give an association a more important role than just being a piece of string between two classes, the association becomes a first-class citizen of your domain and it's justified to make it part of the class model. It's also inevitable, but that's secondary.
So you should map EventTypeDispatchChannels to a class. The table could have its own simple primary key besides the two foreign keys. A simle PK is probably easier, so your table Format can do with a simple foreign key to EventTypeDispatchChannels for the one-to-many association.
You will lose the many to many feature to simply address dispatchChannel.Events. In stead you have to do
db.DispatchChannels.Where(d => d.DispatchChannelID == 1)
.SelectMany(d => d.EventTypeDispatchChannels)
.Select(ed => ed.Event)
On the other hand you have gained the possibility to create an association by just creating an EventTypeDispatchChannel and setting its primitive foreign key values. Many-to-many associations with a transparent junction table can only be set by adding objects to a collection (add an Event to dispatchChannel.Events). This means that the collection must be loaded and you need an Event object, which is more expensive in database round trips.
Suppose the following database schema:
Table A: AId (PK)
Table B: BId (PK)
Table C: CId (PK)
Table AB: AId, BId (composite PK, FKs to A and B), Data
Table BC: BId, CId (composite PK, FKs to B and C), Data
Table ABC: AId, BId, CId, Data
In the database, ABC has two FKs: one to AB on AId and BId, and one to BC on BId and CId.
Use the EF Designer and attempt to create a Model from this database.
If you have Include foreign key columns in the model checked, it works; but having FK Columns in the model isn't very nice.
If you have Include foreign key columns in the model unchecked, only one of the FKs from ABC will be successfully mapped. To see what went wrong, you have to view the .edmx xml (thanks Craig!) and you see this error:
warning 6037: Foreign key constraint 'FK_ABC_BC' has been omitted from the storage model. Column 'BId' of table 'Model.Store.ABC' is a foreign key participating in multiple relationships. A one-to-one Entity Model will not validate since data inconsistency is possible.
I've read the only other mention of this problem I can find on SO, and I don't think this is the same problem. I can't see anything wrong at a database design level. I'm going to work round this for the time being by imposing surrogate keys on AB and BC, but what I'd really like to know is:
What possible data inconsistency is EF worried about happening here, if it created a model to match the database?
And is there anything I can do to persuade it that everything's going to be OK?
My opinion is that EF is too clever in this scenario and it prevents you from using entity where you can assign only one relation and make the entity non-savable because relation to second entity will not exists.
There is also possibility that EF has some internal problem with tracking state of independent associations if more than one association is based on the same foreign key column but that is just another guess. Generally database features used to map EF features cannot be shared among multiple constructions. The only exceptions I can think about now are primary keys and in their own way discriminator columns.
I would like to mention that I don't like this type of relations in database at all.
I would like to map all many-to-may relations through a single table in my database.
Meaning that I have numerous tables (entities) that have various many-to-many relations. Instead of having a separate mapping table for every relation I would like to use one "master mapping" table having to columns: End1Id & End2Id.
Don't ask why ;) It's required by my customer...
How would I set this up in the model designer, or do I have to edit the edmx xml directly....or is it just not possible?
Thanx for your help!
In such a scenario you can't have explicit foreign keys, because a table like this normally has at least three rows:
PK of table 1
PK of table 2
Type of mapping, which specifies the exact tables to use.
Because of that, you can just create a table in EF, but it will also have no connections to other tables and you will have to do the joins manually.
You would need to set this Master Mappings table manually. The designer doesn't do it for you automatically.
However - if denormalized entities are what you are looking for, better have those denormalized in DB level rather than in EF/code level.
I have a Database model like this
FlowObject
FlowObjectID (PK)
Description
Active
ProcessObject
FlowObjectID (PK, FK)
HasSubmit
DecisionObject
FlowObjectID (PK, FK)
YesFlowObjectID (FK)
NoFlowObjectID (FK)
YesCaption
NoCaption
When I try and use create my Entity model I get this warning in my project.
Foreign Key constraint 'FK_ProcessObject_FlowObject1' has been omitted from the storage model. Column 'FlowObjectID' of table 'Investigations.Store.ProcessObject' is a Foreign Key participating in multiple relationships. A one-to-one Entity Model will not validate since data inconsistency is possible.
???
Why did it drop my foreign key? Because "A one-to-one Entity Model will not validate since data inconsistency is possible."
So it sounds like it is saying it dropped the FK because of data inconsistency but dropping the FK actually reduces date consistency?
Should I redesign my database? Is there anyway for L2E to handle FK's that participate in multiple relationships? Is it considered bad database design to have FK's that participate in multiple relationships?
What you've described, translated to object-oriented terms, is that a FlowObject contains an optional ProcessObject and an optional DecisionObject. If this is what you actually meant, the database schema is correct.
If you're trying to have ProcessObject and DecisionObject extend FlowObject, inconsistency is possible because both the ProcessObject and DecisionObject rows may exist. To eliminate the inconsistency, the union-subclass modeling technique is appropriate: only ProcessObject and DecisionObject tables exist, each containing all relevant fields, and FlowObject, as an abstract base class, becomes a view consisting of the union of the common base fields between the two tables.
I have just get the same error when trying to refactor this. In EFv1 (.NET 3.5) this cannot be solved. In EFv4 (.NET 4.0) you can change independent association (the only association/relation available in EFv1) to foreign key association and it will work. But FK associations have some other drawbacks so it is not a silver bullet.