How can Code First be used to map surrogate keys - entity-framework

I have legacy tables with Primary keys. These tables also have surrogate keys that have been used to relate one table to another. I would like to map the Membership.User table (uses a Guid PK) but has a property UserName which holds the surrogate key which relates it to the DepoMembers table. DepoMembers has a numeric PK - but has a surrogate key UserName. UserNames are guaranteed to be unique.
In Linq2SQL - to relate these tables in the designer - we add an association where User.UserName is linked to DepoMembers.UserName - and set the multiplicity of the Association to 1:1. then Modify the Navigation Names to singular.
If we take DepoMembers as the Principal End of the relationship - it should follow that If Membership.User does not exist (As in the case - where a user does not manage the application site but exist in DepoMembers) the Navigation Property User will be Null.
How can this be done in Code First ...
The only alternative I've come up with so far is to create a property DepoMembers.User which uses the UserName Property to retrieve the User using the datacontext.
Ren

Related

Deciding primary key for DynamoDB

I have 3 fields to store in DynamoDB: identity-1, identity-2, score.
identity-1 and identity-2 are always unique in the table, i.e. no two entries can have same identity-1 or identity-2.
We want to allow entries to either have one of identity-1 or identity-2 or have both. Example:
identity-1
identity-2
score
a1
b1
s1
a2
s2
b3
s3
Access patterns are as follows:
Query identity-2 from identity-1
Query score from identity-1
Query score from identity-2
How do I define primary key in such case?
This is a "many:1" problem and there's a few ways to tackle it with DynamoDB. The simple answer here is to leverage Global Secondary Indexes (GSI). For every "identity" you wanted to do a direct look up from, you'd create a GSI.
GSI-1 would include Identity-1 as the hash key and you'd include Identity-2 and any other identities as a non-key attribute to include. You'd create a GSI for each identity you wanted to query directly on. You could also include the score as a non-key attribute if you wanted to directly look up score from any identity without having to resolve to the primary key (which we'll talk about).
The thing to consider with GSI's, though, is that they consume extra storage and throughput. If you create a GSI which includes all your attributes for every identity, you'd be paying for an additional copy of your table for each identity.
The other issue, so far, is that you haven't chosen a Primary Key for your table. You'll need a field to be your primary key and if none of your identities is non-nullable, you'll need a field which will be. It's often convenient to just call it what it is, so we'll call it pk.
You've got a few choices for pk here. Once is to define pk as a composite of your identities. For example: item.pk = item["identity-1"] || item["identity-2"]. Then you could do a query on the table for the identity == pk and if you don't find anything, you could then look up the index for the given identity. This works fine for your simple example, but as you wanted to do more complex things (such as many different identity types), you might find it to be a bit of a headache.
From past experience, my recommendation would be to adjust your approach slightly, however, and have an "users" table and a "scores" table. "users" would have a pk of a guid unique for every user and all their identities (call it "user_id"), you could then create a GSI for that table for every identity back to user_id. Then scores would then use "user_id" as the pk as well with no need for an index. Your application would always resolve to a "user_id" when a user was logged in or otherwise identified - then you can search for score without needing to track identity and you can look up all the associated identities or other user information without needing to create a very "fat" index of every identity->every other identity.

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.

Cannot get the Entity Framework to handle a GUID relationship

I am trying to achieve the following end result. My Person entity needs a collection of extra values and this collection of values will vary from Person instance to instance. I also have another Contact entity that likewise can have extra values form instance to instance.
Therefore I need three tables, a Person, Contact and an Extra where the Extra has the set of extra values for each Person and Contact instance that needs extra values. By giving the Person and Contact a GUID field it means that the GUID values will be unique across both tables and so I can use that as the field to join on. So I expect the definition to look like this...
Person
Id - int - Primary Key
Instance - GUID - Unique Constraint
Contact
Id - int - Primary Key
Instance - GUID - Unique Constraint
Extra
Id - int - Primary Key
Instance - GUID
Value - string
But I cannot model this into Entity Framework. I would like my Person and Contact entities to have a collection each that is the set of Extra values that are relevant to that entity. I create the three tables with the set of columns as indicated above.
But I cannot get the association to work as expected, it always wants to add extra columns to the database based on the primary key of the Person and Contact entities. Any ideas how to actually get this to work? Or maybe this is not possible in EF?
This is not possible with EF because it doesn't support unique keys. Only primary keys can be used as principal in relation.
As answered already, EF does not support unique keys. However, if you don't actually need to do anything with the Id property, it may suffice to tell EF that Instance is the primary key. EF doesn't really care whether it's the primary key at the database level, it merely needs to know whether it can use it as a key itself.
Edit: actually, that still wouldn't work. Besides not supporting unique keys, your Extra.Instance does not correspond to any fixed entity. In order to get it working, you would need to split the Extra table into PersonExtra and ContactExtra tables. That's probably a good idea regardless, as it allows you to add the foreign key constraints at the database level that correspond to those you wish to see in EF.
The EF way of doing this is to use a linking table - a simple table that has two columns, which will be not be visible in your model directly but the collections will be.
e.g.
Person
Id - int - Primary Key
Instance - GUID - Unique Constraint
Contact
Id - int - Primary Key
Instance - GUID - Unique Constraint
Extra
Id - int - Primary Key
Instance - GUID
Value - string
PersonExtra
PersonId - int
ExtraId - int
ContactExtra
ContactId - int
ExtraId - int
or change your Primary Key to be the GUID if your model will permit this.

Linq Mapping Problem with 1 to 0.1 relationships

I have an linq to entity mapping issue. I have three tables.
Table 1 - ItemsB(ID(key), Part_Number(will be null until built), other item b information)
Table 2 - ItemsA(ID(key), Part_Number(will be null until built), other item a information)
Table 3 - WebItems(Item_id, web item information) *Consists of items from both ItemsB and ItemsA after they are built and pushed over to this table.
ItemsA/ItemsB will have a 1 to 0.1 relationship with WebItems. Part_Number maps to Item_id.
I am using EF4.0.
Problem is after i set up the association/mappings as stated above i get an error message stating: "Problem in mapping fragment at lines so and so: Column [Part_Number] are being mapped in both fragments to different conceptual side properties."
Usually i know what to do in this case. Get rid of the property [Part_Number]. Problem is i need to access [Part_Number] in both ItemsB and ItemsA quite frequently without going to webitems. Not to mention webitems will not always have the [Part_Number] populated at certain points depending upon whether the items have be pushed to webitems.
Does anyone know how to get around this?
Thanks in advance.
As I understand it ItemA and ItemB to WebItem in one-to-one relation. One-to-one relation in EF always demands that relation is build on primary keys and one side is mandatory (principal) because dependent entity will have primary key and foreign key in one column. Once you assign primary key in dependent entity you must have principal entity with the same primary key otherwise you will violate referential integrity defined by foreign key.
The problem is that your Part_Number is primary key and foreign key in the same time. To allow such mapping in EFv4 you must use Foreign Key association instead of Independent association. Here is brief description how to create foreign key association in the designer. Once you define referential constrain get back to mapping window of association and delete the mapping.

How can you make an association without using all entity keys in entity framework?

I'm getting more and more frustrated with EF...
I have a table called ExtendedField with:
Record
DocRef
DocType
Name
Record is the primary key
DocRef and DocType are foreign keys used to identify which Ticket they belong to
Name is the key used by the "definition" table to define what the field actually is
So basically I need 2 associations:
One between Ticket and ExtendedField
on ExtendedField.DocRef=ticket.record
and
ExtendedField.docType=HeaderDocType
One between Definition on
ExtendedField.Name=Definition.FieldName
Then I still need Record to be the primary key so I can directly access the fields.
As near as I can tell this is impossible to do in Entity Framework. For every association all the keys need to be mapped together, whereas I need two keys for one association, 1 key for another one and the actual primary key wouldn't be used in any associations.
It doesn't appear that you can define an association between fields that aren't entity keys either.
So is there any way to do this? Am I missing something?
It's a v1, bro. I myself have had some major pain with mapping of key constraints in EF. I hear that better things are coming in v2.