I have multiple issues with EF 2.1 Core, both issues do not exist in my current production EF6 implementation... This post is about my first issue. The second problem i will detail is a bit more complex, but will save that for another post.
I have, for the purposes of this post, a parent\child relationship with two SQL Server tables;
Device Table
DeviceID int (autoincrement key)
Name varchar(50)
More fields...
Events Table
DeviceID { half composite key, one to many relationship with parent}
EventStamp DateTime { half of composite key }
EventText varchar(max)
More fields...
So, in my previous iteration (EF6) I ran scaffolding in VS 2015 (database first implementation) and it gave me all my classes, and database context. I placed them in my web api 2 application, defined the ODATA 4 IEDMModel, used the model builder and like magic I had an OData 4 web service that supplied all my information to my custom mobile app...
In the previous app, I was able to hit the service like "http://server/devices" and I would get a full list of ALL devices. adding (N) where N is a number, would find the specific single indexed entity. I could then append ...devices(4)/events... and I would get ALL the events for that device... and with some odata query syntax i could get specific detail from within the event entity... BEAUTIFUL! Simple ODATA 4 query syntax is the real power here! Including reversing the scenario... going reverse lookup from the events first was extremely helpful.
In order for Odata 4 to work, I have to define the EDM model. In EF6 everything works just fine. In EF Core 2.1. The "Events" table throws an error on running the web service... Table "Events" does not have a primary key. This in fact is NOT true, and this was not a problem in the previous EF6 version, using ODATA 4. I tried several different theories, including Fluent approach, but nothing changes the fact that in the "startup.cs" I get the error early, while the system is initializing...
Anybody have a thought here?
Related
So I'm creating a database model using Entity Framework's Code First paradigm and I'm trying to create two tables (Players and Teams) that must share a uniqueness constraint regarding their primary key.
For example, I have 3 Players with Ids "1", "2" and "3" and when I try to create a Team with Id "2", the system should validate uniqueness and fail because there already exists a Player with Id "2".
Is this possible with data annotations? Both these entities share a common Interface called IParticipant if that helps!
Txs in advance lads!
The scenario you are describing here isn't really ideal. This isn't really a restriction on Entity Framework; it's more a restriction on the database stack. By default, the Id primary key is an Identity column, and SQL itself isn't really supportive of the idea of "shared" Identity columns. You can disable Identity and manage the Id properties yourself, but then Entity Framework cannot automatically build navigation properties for your entities.
The best option here is to use one single participant table, in a technique called "Table Per Hierarchy", or TPH. Entity Framework can manage the single table using an internal discriminator column. Shared properties can be put into the base class, and non-shared properties can be put on the individual classes, which Entity Framework will composite into a single large table in the DB. The main drawback to this strategy is that columns for non-shared properties will automatically be nullable in the database. This article describes this scenario very well.
The more I try to come up with a solution, I realize that this is an example of the XY Problem. There is not really a good solution to this question, because this question is already a proposed solution. There is a problem here that has led you to create an Interface which you suggest requires the entities which are using the interface to have a unique Id. This really sounds like an issue with the design of the Interface itself, as Interfaces should be agnostic to the entity they are applied to. Perhaps providing some code and showing what your problem actually is would be helpful, since the proposed solution you are asking how to implement here isn't really practical.
I did work on ADO.NET Entity Framework v2 about two years ago. I have faint memories.
Incidentally, I happen to be working in a very secured (for want of a euphemism) environment where a lot of links are blocked and there's not much one can do. It does get in the way of studying and working, more than a bit.
Therefore, I have to rely on this forum for a few basic questions I have to get started again. This time, I am working on Entity Framework 4. Here are my questions.
All these questions relate to the EDM generated entities, i.e. not the Code First model.
1) Is my understanding correct? I can rename any column name in the EDM designer generated model and nothing breaks.
2) Foreign keys are expressed as navigational properties in the generated entity classes. No special consideration is required to maintain foreign key relationships. I recall in version 1 of EF, you had just ID properties and the navigational IQueryable/IEnumerable/EntityCollection/RelatedEnd properties were introduced in version 2. I just need to know if I need to do anything to retain/maintain foreign key relationships and referential data integrity. I assume I don't need to. A confirmation would be nice.
3) What are all the possible ways to execute a stored procedure? I recall -- one way to use ExecuteSQL or something on the Context.Database object, another to use EntityClient API and the third was to specify stored procedure names in the InsertCommand, SelectCommand, etc. thingies in the mapping window of the EDM designer. Is this correct?
4) How do you use those SelectCommand thingies in the mapping window on an entity? Do you just supply the names of the stored procedures or user defined SQL functions?
5) How do I create an entity out of a subset of a table? Do I just create an entity from the table and then delete the columns I don't need from the designer? What happens if there are required (NOT NULL in SQL) values that are not in the subset I choose?
6) How do I create a table out of a query or join of two or more tables.
1) You can rename columns in the designer and nothing should break (if the name is valid)
2) Navigation properties point to related entities. In EF4 foreign keys were added. Foreign key properties basically expose the database way of handling relations. However, they are helpful since you don't have to load related entities just to change relationship - you can just change the key value to the id of the other entity and save your changes
3) Yes. You can either execute the procedure directly - this is for stored procedures that are not related to CUD (Create/Update/Delete) operations. You can map CUD operations to stored procedure as opposed to having EF execute SQL statements it came up with for your CUD operations.
4) I think this is a bit out of scope - you probably can find a lot of blogs with images how to do it. Any decent book on EF should also have a chapter (or two) on this. Post a question to stackoverflow if you hit a specific problem.
5) Remove properties in the designer and then supply default value to the S-Space definition. I believe you cannot do this with the designer. You need to rightclick on the edmx file and open it with the Xml editor and manually edit it. Also see this: Issue in EF, mapping fragment,no default value and is not nullable
6) You can either create a view in the database or you can create entity set using E-SQL in your edmx file (I think this will be read only though) or you may be able to use Entity Splitting. Each of these is probably a big topic itself so I think you should find more about these and come back if you have more specific questions / problems
How to implement in EF5 a KeyTable style identity method
"Uses a table in the database to store the next Id, and advances this value every time a new block of Ids is required" from LightSpeed
I believe this is like Oracle sequences.
This feels like it should be easy (as it is in LightSpeed). This gives the ORM an easy way to do bulk inserts ie it can get 10 identities at a time, then do a bulk insert back to the db.
Am using EF5 / WCF RIA Services (latest) talking to Silverlight. The rest of the project uses bulk insert SSIS stuff.. and the SL project does some inserting. So I need to follow this convention.
I guess the question is fundamentally more about whether Entity Framework can support this style of key generation, and a secondary part of the question is whether RIA Services would integrate OK with that.
It reminds me of the range of key generation strategies that are available in NHibernate.
Here's an answer here which suggests that EF does not have such full support as NHibernate 'out of the box':
Unfortunately, EF doesn't have anything very close to the POID
generators like NHibernate does, although I hear rumors that similar
capabilities will be included in the next release of EF.
from HiLO for the Entity Framework
This answer suggests that it's not too tricky to intercept a Save (specifically an insert) in RIA Services and call a SPROC to get the new ID
you only need to call stored procedure to get a value before you are
going to save the record [can put this into an] overriden
SaveChanges() in your context
see https://stackoverflow.com/a/5924487/5351 in answer to What is the best way to manually generate Primary Keys in Entity Framework 4.1 Code First
and a similar answer here... https://stackoverflow.com/a/5277642/5351
Here are some findings on possibly implementing a HiLo generator (a more robust key gen pattern) with EF:
The Hi/Lo pattern describe a mechanism for generating safe-ids on the
client side rather than the database. Safe in this context means
without collisions. This pattern is interesting for three reasons:
It doesn’t break the Unit of Work pattern (check this link and this other one)
It doesn’t need many round-trips as the Sequence generator in other DBMS.
It generates human readable identifier unlike to GUID techniques.
from http://joseoncode.com/2011/03/23/hilo-for-entityframework/
I am trying to create WCF Data service project using Entity Framework. ( I am new to both).
I created entities using DB.
Now, I created service operation, which returns the IQueryable<entity>.
My problem is
I do not want to return the entire set of columns in the entity. I cannot delete them from the entity as it is not null. How to avoid these?
I have few FK columns and I need other column details of the table. How to include columns from other table?
Why it is not possible to use POCO class to be returned from WCF Data service?
How do I format the response; i.e., add few more details to the response like page number etc, change the xml tags, remove few details like "link rel"?
I have tried a lot of things to achieve 1 and 2. But finally I realised that I can only use the entity as it is to make it work.
I have no idea about 4.
Any suggestions would be appreciated.
1. I do not want to return the entire set of columns in the entity.
2. I have few FK columns and I need other column details of the
table.
For this, you should define a new class that matches what you need / what you want your clients to see. That can be a straight POCO class - no special requirements. Assemble that class for each entity, leaving out the unwanted columns, and grabbing the extra field or two for the FK columns into that new class. Return an IQueryable<YourNewClass> instead of the entity class directly.
To avoid huge left-right-assignment statements just to fill the properties of the new class, you should have a look at AutoMapper which makes it really easy to copy around classes that are very similar to one another (e.g. missing or adding a few properties).
4. How do I format the response; i.e., add few more details to the
response like page number etc, change the xml tags, remove few details
like "link rel"?
That's not possible - the OData protocol very strictly defines what's going to be in the message, what links there are etc. If you can't live with that - you'll have to roll your own WCF REST service and drop the WCF Data Service stuff altogether.
Check out the WCF REST Developer Center on MSDN if you want to investigate that route more thoroughly.
Update: that link seems to have gone dead - try WCF Web Http Programming Overview instead.
Make sure you have an Id property or you specify either [Key] or [DataServiceKey("Your_Custom_ID_Property")]
For me this sorted out the issue
I'm working on a C#.NET 3.5 WCF RIA Services app and having an issue with my Entity Framework model.
My entity Foo is mapped to a DB table and has a primary key called FooId. My Bar is mapped to a DB view. I've selectively designed this view to generate a composite key in the EF using two of the columns (by making sure they were non-nullable and the others are all nullable. This was done using NULLIF and ISNULL in the view design.)
I'm able to add this view to the model with no problem but I keep running into an issue when I try to map an association between the two. Foo should contain many Bars but I keep getting the following error when I add the association:
Unable to retrieve AssociationType for
association 'FK_Bar_Foo'
According to this page, it looks like this might work if I can properly name the association (since RIA Services looks for specific names.) I've tried several variants of names that match the pattern of other associations with no success. Does anyone know if there's a place I can look to find out what name it's looking for?
Thanks,
After some research I found a workaround to the issue here. The problem with this solution is that you have to repeat it every time the model is updated, which just won't work for me. It appears the current version of the EF doesn't support this type of relation.
The solution I finally went with was to redesign the client to independently call the service and request an entity collection by passing the primary key (FooId) of my Foo type. It's not the best approach (and requires a lot more manual coding) but it does the job. I hope Entity Framework version 4 solves this limitation.