In the L2S designer I have dropped a table and a view. I tried adding an association between the 2 on their primary keys. This should be a one-to-one relationship, so I set the cardinality property of the association as such.
But, when coding I can't access the child property.
Any suggestions?
EditI just created a view in sql server that has the fields I want, and dropped that into L2S. Much simpler.
In my experience Linq To SQL requires the Primary/Foreign key relationships established in the DB. Otherwise, you'll have to do a join.
Not sure if this applies to your situation, but it may...
Linq To SQL Without Explicit Foreign Key Relationships
UPDATE:
It appears that you can get what you're looking for without establishing the Primary/Foreign key relationships in the database. In the LinqToSQL designer set primary keys on both columns on each table. I also had to turn off Auto-Sync on Parent Table's column that I assigned as a primary key.
Auto-Sync is described here..
Instructs the common language runtime (CLR) to retrieve the value after an insert or update operation.
Link:
http://msdn.microsoft.com/en-us/library/bb386971.aspx
We had this problem with views.
We simply defined the keys in the DBML editor and the property was finally defined.
Did you disable (set to false) either the child or parent property?
Did you perhaps mapped the one-to-one relationship the wrong way around (like I did less than an hour ago)?
Related
I choose Database First:
Here is an example table that is experiencing this issue. As you can see the EntityId column is the Primary Key:
The imported table in the model browser shows that it has the Primary Key:
But the code for the generated class does not have the EntityId column decorated with a Key attribute:
At run time I get this error:
Additional information: One or more validation errors were detected
during model generation: EntityType 'Entity' has no key defined.
Define the key for this EntityType.
Why do I have to manually decorate the EntityId column with the Key Attribtue? Shouldnt EntityFramework take care of all that considering it is Database first?
Typically speaking I have experience with EF4 through EF 6.1.3 and a teeny bit with Entity Core (was EF7 and then MS fun with naming). Typically if you are doing database first you do not get an adornment from your t4 template. I just looked at mine just now and I have no adornment for the key, just for constructor and the reference to the navigation of teOrder back to it.
I can save an Entity just fine and my code runs with this:
using (var context = new EntityTesting.TesterEntities())
{
var nPerson = new tePerson { FirstName = "Test", LastName = "Tester" };
context.tePerson.Add(nPerson);
context.SaveChanges();
}
What I would suggest is:
Go to your (name).edmx Entity File and on the design surface wipe out the object and then replace it on the surface. In countless times this has fixed issues with the generated objects. When you SAVE it should auto run the T4 templates (*.tt files). If not you can select them, right click and select 'Run Custom Tool'. This just generates the POCO objects or the Context objects.
If this is really a fault with the table it is typically with it NOT having a key. You are showing it does though. Is there anyway to mirror the exact same table logic and confirm the key has nothing out of the ordinary and is just a plain old key Primary Key?
Create a brand new table with similar structure but not an exact copy and a new Entity File and confirm you can create it.
Tables are pretty straight forward with EF, or as straight forward as EF can be. You create them in SQL, ensure you have a key, add it to a design surface, save, it generates the objects for you. If you have other things under the hood like custom procs hooked to it or other out of the ordinary nav items that would be one thing. The only other thing would be if it has a very old SQL Type as the key. I know that the 'Text' type and EF do not play nice together. There may be other types that behave the same way.
This issue was fixed by including the "metadata" part of the connection string.
At first my connection string looked like this:
data source=.;initial catalog=TestDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework;
Which produced the error.
Changing my connection string to this:
metadata=res://*/DbContexts.TestContext.csdl|res://*/DbContexts.TestContext.ssdl|res://*/DbContexts.TestContext.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=TestDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
Allowed operations on the Context to be performed with no error encountered
I have a DBFirst EntityFramework 6.1 solution that i'm trying to generate off of. When i add a table that only contains two foreign keys the table is turned into two associations and I can not directly access the table anymore. This is neat for navigation in the code but makes it a pain in the ass to delete records from the table.
Is there a way to prevent this behavior and gain direct access to the table as an entity?
For example i am unable to remove an entry in the association because i get this error
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
For example here is how my database sees the structure.
Here is how it appears in entity framework. Notice that the CorporateDataShareVisible table is missing and instead two new associations are created.
The CorporateDataShareVisible table should be able to be deleted and added to at will but any changes i make seem to stop it from working.
Add a primary key to your table that has only foreign keys. EF uses the primary key to keep track internally of the element. Without a primary key it doesnt know which element was modified and how to send that back to your RDBMS.
I prefer surrogate keys i.e auto incrementing integers.
You can also add the primary key by making it a composite key of both the foreign keys
I'm using generated POCO classes and Entity Framework.
In order to make the code less complex I'm trying to remove all navigation properties from the code while still keeping the Foreign Key constraints in the database (navigation properties do more harm than good for us).
If I remove them manually from the POCO-classes I get the following error
The entity type UserEntity is not part of the model for the current context
If I try to remove them from the .edmx-file I get the following error:
Error 3 Error 3015: Problem in mapping fragments starting at lines 479, 562:Foreign key constraint 'fk_StorageContracts_User1' from table StorageContract (OwnerUserID) to table User (ID):: Insufficient mapping: Foreign key must be mapped to some AssociationSet or EntitySets participating in a foreign key association on the conceptual side.
Is there any way to remove navigation properties from POCO-classes without removing the corresponding FK?
I know this is old, but, since there is still no answer, I thought I'd give it a try:
I am still working in EF 4.0, but, following the example to which you referred, you have an xxxModel.tt. If you are willing to tweak that, you can find where it generates the Navigation Properties and change them to be simple auto-properties. I had a similar project where I generated them like this:
public List<NavDataX> NavDataXs
{
get; set;
}
Now, they are still there, but they are null until you explicitly set them. Doing it this way, I did not mess with the EDMX and did not encounter the two errors you mentioned.
In the screenshot below is an Entity (URL) in my model. The ParentId field is a self-referencing FK (points to Url.Id). You can see this navigation at the bottom of the screenshot.
In my SQL and my DB, which I generate the EDMX from, the self-referencing FK is called FK_Urls_Parent:
-- Creating foreign key on [ParentId] in table 'Urls'
ALTER TABLE [Urls]
ADD CONSTRAINT [FK_Urls_Parent]
FOREIGN KEY ([ParentId])
REFERENCES [Urls]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
My questions are:
Why did EF generate Urls1 and Url1 just from that one FK? Url1 is a 0 or 1 property that is 'FromRole' Urls1. Urls1 is 'FromRole' Urls 'ToRole' Urls1. It seems like EF is making a navigation property that is the exact same as Url table. Why would it do this and can I do something to make it just generate the one, desired Navigation property: Urls1?
Okay, so not quite as important, but can I control the name of the Navigation property based on the FK name or something in the DB? I hate that it names it 'Url1'. I would prefer 'Parent', but don't want to have to manually change it in the designer every time I regenerate the model.
Thanks.
It is modeling both sides of the relationship. In other words, one of the properties will be the entry being pointed to by this entry's ParentId. The other will be the entry(s) whose ParentId field points to this entry. You can disable one side in the relationship properties, or rename them to make sense. Such as, for instance, ParentUrl and ChildUrls.
I'm not 100% certain how to get to the property relation dialog without opening the program myself, which I can't right now. I do know for me it appears in the (by default) bottom-right properties window when the link is selected.
As far as making this change somehow permanent across model regenerations, I know of no way to do this. Hopefully someone else will know, because it would save me a lot of time too!
I currently have a Entity Framework 4.0 model in place with Table Per Type (TPT), but there are a few performance issues (lots of LOJ's/CASE statements), as well as an issue mapping between two particular domain areas (many-to-many).
I've decided to try out TPH.
I have an entity called "Location" which is abstract, and the base for all other entities.
I then have "Country", "City", "State", "Street", etc which all derive from Location.
"LocationType" is the dicriminator.
That part is working fine, but i'm having issues trying to define navigational properties for the derived types.
For instance, a "State" has a single "Country", so i should be able to do this:
var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;
But this would require a navigational property called "Country" on the "State" derived entity. How do i do this? When i generate the model from the database, i have a single table with all the FK's pointing to records in the same table:
(NOTE: I created those FK's manually in the DB).
But the FK's are placed as nav's on the "Location" entity, so how do i move these navigational properties down to the derived entities? I can't copy+paste the navs across, and i can't "create new navigational property", because it won't let me define the start/end role.
How do we do this?
It's also not clear with TPH if we can do it model-first, or we HAVE to start with a DB, fix up the model then re-generate the DB. I am yet to find a good example on the internet about how to define navs on children with TPH.
NOTE: I do not want to do code-first. My current solution has TPT with the EDMX, and pure POCO's, i am hoping to not affect the domain model/repositories (if possible), and just update the EF Model/database.
EDIT
Still no solution - however im trying to do model-first, and doing Add -> New Association, which does in fact allow me to add a nav to the derived entities. But when i try and "Generate database from Model", it still tries to create tables for "Location_Street", "Location_Country" etc. It's almost like TPH cannot be done model first.
EDIT
Here is my current model:
The validation error i am currently getting:
Error 1 Error 3002: Problem in mapping
fragments starting at line
359:Potential runtime violation of
table Locations's keys
(Locations.LocationId): Columns
(Locations.LocationId) are mapped to
EntitySet NeighbourhoodZipCode's
properties
(NeighbourhoodZipCode.Neighbourhood.LocationId)
on the conceptual side but they do not
form the EntitySet's key properties
(NeighbourhoodZipCode.Neighbourhood.LocationId,
NeighbourhoodZipCode.ZipCode.LocationId).
Just thought i'd keep editing this question with edit's regarding where i am currently at. I'm beginning to wonder if TPH with self-referencing FK's is even possible.
EDIT
So i figured out the above error, that was because i was missing the join-table for the Neighbourhood-ZipCode many to many.
Adding the join table (and mapping the navs to that) solved the above error.
But now im getting this error:
Error 3032: Problem in mapping
fragments starting at lines 373,
382:Condition members
'Locations.StateLocationId' have
duplicate condition values.
If i have a look at the CSDL, here is the association mapping for "CountyState" (a State has many counties, a County has 1 state):
<AssociationSetMapping Name="CountyState" TypeName="Locations.CountyState" StoreEntitySet="Locations">
<EndProperty Name="State">
<ScalarProperty Name="LocationId" ColumnName="StateLocationId" />
</EndProperty>
<EndProperty Name="County">
<ScalarProperty Name="LocationId" ColumnName="LocationId" />
</EndProperty>
<Condition ColumnName="StateLocationId" IsNull="false" />
</AssociationSetMapping>
It's that Condition ColumnName="StateLocationId" which is complaining, because ZipCodeState association also this condition.
But i don't get it. The discriminators for all entities are unique (i have triple checked), and i would have thought this was a valid scenario:
County has a single State, denoted by StateLocationId (Locations table)
ZipCode has a single State, denoted by StateLocationId (Locations table)
Is that not valid in TPH?
So i solved a few of my issues, but i hit a brick wall.
First of all, when you create self-referencing FK's in the database side, when you try and "Update Model from Database", Entity Framework will add these navigational properties to the main base type, as it has no explicit sense of TPH - you need to do this in the model side.
BUT, you can manually add the navigational properties to the child types.
WRT this error:
Error 3032: Problem in mapping fragments starting at lines 373, 382:Condition members 'Locations.StateLocationId' have duplicate condition values.
That was because i had an FK called "Location_State" which i was attempting to use for the "ZipCode_State" relationship, AND the "City_State" relationship - which does not work (still no idea why).
So to solve that, i had to add extra columns and extra FK's - one called "ZipCode_State", and another called "City_State" - obviously it has to be a 1-1 between navs and physical FK's.
Location.LocationType has no default value and is not nullable. A column value is required to store entity data.
That is my discriminator field. In the database side, it is not nullable.
I read threads about this issue, and they said you need to change the relationships from 0..* to 1..* - but my relationships already were 1..*.
If you look at my "Locations" actual database table above, all the FK's are nullable (they have to be). Therefore i started wondering if my relationships should be 0..*.
But they are nullable because of the TPH - not all "Locations" will have a "State". But if that Location is a "City", then it HAS to have a "State".
My feelings were further comforted by this SO question: ADO EF - Errors Mapping Associations between Derived Types in TPH
I was actually trying that workaround (before i even came across it), and the workaround does not work for me. I even tried changing all the relationships from 1..* to 0..*, and still no luck.
Wasting too much time here, I've gone back to TPT.
At the end of the day, with TPH i would have had a ridiculously large table, with lots and lots of redundant, nullable columns. JOIN-wise, it's more efficient. But at least with TPT i am not required to have nullable and self-referencing FK's.
If anyone has a solution to this problem, let me know. But until then, im sticking with TPT.