EF Code First From DB not creating Entities for all tables - c#

I have an existing Database I am trying to use Entity Framework Code First From Database to generate C# entities for. To do this I am doing Add -> New Item -> ADO.NET Entity Data Model -> Code First from database inside Visual Studio 2015. When I go though the Entity Data Model Wizard I see that every table is selected but when the import finishes entities for some of the tables where not created. I have tried this twice and double checked that the table with no entities are indeed selected for import. No errors are thrown during the import so I am not sure why some of the tables are missing there entitles. What might be going wrong and how do I get an entities for every single selected table?
SQL Create Table Code for one of the missing tables:
CREATE TABLE [dbo].[ProgramControl] (
[CodeName] VARCHAR (80) NULL,
[CodeValue1] VARCHAR (50) NULL,
[CodeValue2] VARCHAR (50) NULL,
[CodeValue3] VARCHAR (50) NULL,
[CodeValue4] VARCHAR (50) NULL,
[Description] TEXT NULL
);

EF code-first requires the use of a primary key on every entity, so the tool is not able to map these tables.
It looks like you might be able to work around this with some trickery, but adding a PK to every table is almost certainly the best approach.

If Table does not have at least one parameter not null ADO.NET will not generate the class. I don't know if it is a bug, just happened to me.
It is not necessary to have a primary key but a not null.

Related

How do I working with objects that can change from one client to another

I have a problem where I data for an object, for example billing file, where the data elements are different from client to client. More specifically the number of fields within the data and of different names. I am looking for a solution when working with the objects in C#.
Currently I have created tables for each client. The fields are specific to the client and I use a mapping process when uploading data. I also have dynamic queries in SQL Server to handle all crud processes. It all works pretty well but I believe there is a better solution and I believe saving Json data would be one of them. Pulling the Data I first query the headers of the table and then map the data to those headers for data grids and such. Again, I already have a working solution, but I believe there is a better solution and I am looking for suggestions with examples. By the way, I have thought about dynamic object, in C#, but it would appear you have to know what fields of the object are upfront.
I suggest that you should create mapping table, but there is no need to use something like dynamic sql, here are tables:
create table d_billing_object -- one row here means one field from your question
(
id int not null identity (1, 1) primary key
,name nvarchar(255) not null
)
create table d_billing_client
(
id int not null identity (1, 1) primary key
,name nvarchar(255) not null
)
create table d_billing_mapping
(
billing_client_id int not null
,client_billing_object_id int not null
,billing_object_id int not null
,constraint PK_d_billing_mapping primary key (billing_client_id, client_billing_object_id, billing_object_id)
,constraint FK_d_billing_mapping_d_billing_object foreign key (client_billing_object_id) references d_billing_object (id)
,constraint FK_d_billing_mapping_d_billing_object_2 foreign key (billing_object_id) references d_billing_object (id)
,constraint FK_d_billing_mapping_d_billing_client foreign key (billing_client_id) references d_billing_client (id)
)
After that you just need to create all billing objects and use them in mapping table for all clients you have.

Can't access Entity Framework table with no primary key

I am creating an application to transfer data from one database into another for a new application and I am running into an issue access some of the data in the old database. The old database was created using Ruby on Rails and they way it was designed and created through Rails, the database in SQL Server has no primary keys and all the columns are nullable. The new database was designed and built in SQL Server with proper keys and nullable columns. Since both databases are in SQL Server I wanted to use Entity Framework Database First to make the data transition easier.
In the EF Desginer I was able to assign entity keys to all of the tables except for one (Response), which is keeping me from correctly accessing the data in the table. The table definition is as follows:
assess_id [int] NULL
person_id [int] NULL
question_id [int] NULL
question_version [int] NULL
answer_id [int] NULL
answer_version [int] NULL
text [nvarchar(4000)] NULL
created_at [datetime] NOT NULL
updated_at [datetime] NOT NULL
Because of the allowed records the primary key should consist of
assess_id
person_id
question_id
question_version
answer_id
answer_version
but there may be multiple answer_id and answer_version records to the same question_id and question_version or the answer_id and answer_version are null so I cannot use that. Any subset of this key would not allow me to properly retrieve all the data. Also I cannot use the created_at or updated_at columns as there are multiple instances of rows being written with the same time stamp.
I only need to read the data, not write, since it is being transformed into the new database and there is no way for me to change the existing database. Is there any way around the key issue?
Before I answer I would like to point out that this solution only works for read-only situations and if you need to write to the table it will not help. In that case I point you to this answer where you will find some help.
I managed to find a work around for this scenario and while easy enough to use, I would not consider it optimal.
In order to get around the key issue, I picked a primary key that would at least not fail a null check, in this case just the assess_id and person_id columns. This let me build without any errors but I still could not retrieve all the data correctly.
The workaround is to use a SqlQuery on the database.
var responses = context.Database.SqlQuery<Response>("SELECT * FROM dbo.responses");
This executed the query on the whole database and casted the result set into a list of responses with the correct data. Make sure you execute the query on the database and not the table, otherwise the incorrect key specified in the designer will be used and you won't get the correct data back.
Put your SQL in a stored procedure and call that from your application.
If you cannot modify the source database, you can put the stored procedure in the destination.

Persisting Object Graph to SQL Server in a single transaction

I am having an issue coming up with a solution that I think must be a common problem to be solved by anyone writing to a database. I keep thinking that there is an obvious solution that I'm overlooking and that's why I can't find an appropriate existing question here.
Imagine a situation where you need to let a user create a "Class", with "Students", and each "Student" is assigned one or more books. You have a well defined hierarchy, Class->Student->Book.
You have the following tables:
CREATE TABLE Classes (
ClassId int identity(1,1) primary key,
ClassName nvarchar(255)
)
CREATE TABLE Students (
StudentId int identity(1,1) primary key,
ClassId int,
StudentName nvarchar(255),
StudentImage image
)
CREATE TABLE StudentBooks (
StudentBookId int identity(1,1) primary key,
StudentId int,
BookName nvarchar(255)
)
With this contrived scenario, what are my options for saving this entire graph of new objects, while letting SQL server assign the identity columns, and keeping it all in one transaction? Assuming that a class has maybe 30 students, and each student has several books assigned.
I could create a transaction and make a separate call for each row in each table, returning SCOPE_IDENTITY for each new parent object so I can save each child while keeping RI intact.
I could use XML. I would like to avoid that, as the graph includes a byte array.
Any other options? I thought about passing each level of the hierarchy in a table parameter. I'm not sure how or if that would work. (Wouldn't I have to define a table type for each of my tables, essentially duplicating the schema?)
I can use SQL server 2012 for this.
Thank you!
You can use Entity Framework to achieve what you want.
There are lots of tutorials out there, but a good starting point is this one:
MSDN on getting started with Entity Framework
or the linked page
MSDN overview page on getting started
I would recommend the EDMX approach for your use-case.

C# Entity Framework: Update Query Does not work

I have this simple code : (update value)
I'm trying to update column "c"
using (MaxEntities ctx = new MaxEntities())
{
aa orders = (from order in ctx.aa
select order).First();
orders.c = 22;
ctx.SaveChanges();
}
this is the table :
CREATE TABLE [dbo].[aa](
[a] [int] NULL,
[b] [int] NOT NULL,
[c] [int] NOT NULL
) ON [PRIMARY]
and values inside :
but i get an exception :
The property 'c' is part of the object's key information and cannot be modified.
I'm new to EF.
any help will be much appreciated.
The property 'c' is part of the object's key information and cannot be modified.
That's why you can't edit it. Maybe you need to add id column as a key with identity specified
As explained in another answer EF must uniquely identify every entity. If you don't have PK in the database, EF will infer some key. Key is considered as fixed so if EF inferred c as part of the key (and it did it because it uses all non-nullable non-binary columns) you cannot change its value. Moreover EF takes all tables without primary key as readonly so even if you remove c from the key in the designer and modify c value you will get another exception when you execute SaveChanges.
The reason for the second exception is in the way how EF describes model and the database. When EF inferred key, it did it only for description of your entities and for context's internal needs but not for description of the database. When EF tries to save changes it builds UPDATE statement from database description and without information about real database PK columns it will not be able to identify correct record for update (every update in EF can affect only single record - EF checks ROWCOUNT). This can be solved by cheating EF and updating its database description = by describing some column in the table description as primary key. This leads to multiple problems:
You must have some unique column in the database otherwise this method will not work.
You must edit EDMX manually (as XML) to add this change
You must not use default MS EDMX designer for updating your model from database because it will delete your change
Simple advice: Either use database tables with primary keys or don't use Entity framework.
Primary key missing here. Add primary key in table and it work.
I believe if there's no PK at all, EF uses all of the fields/columns as part of the key info.Here's a nice explanation: by #SteveWilkes of why. But what do your entities look like? The other possibility is that it doesn't have a property because the association is inside a different entity, if this is a foreign key.
EDIT
This got me thinking. There are just going to be situations where you have to work with legacy tables having no PK, even if you would never create such a thing. What about views? EF is a mapper - it has to uniquely identify that record so it infers and defines this key. Yes, you could use stored procedures, but could you also hack the XML and remove the keys from the table definition?
AND EDIT AGAIN
After posting this, I see #Ladislav Mrnka already said a similar idea (cheating EF and updating its database description), so it has been done (WARNING: Consume at your own risk - never tried). Quick google got me this blog with clear instructions:
Close the model designer in Visual Studio if it is still open and re-open the .edmx file in an XML editor
Find the edmx:StorageModels -> Schema -> Entity Container -> EntitySet element that refers to the table in question
On the EntitySet element, rename the store:Schema attribute to Schema
Remove the store:Name attribute altogether
Remove the opening and closing DefiningQuery tags and everything in between them
Save and close the .edmx file
But really, who doesn't like a PK? Can you not add an id?

Entity Framework doesn't like 0..1 to * relationships

I have a database framework where I have two tables. The first table has a single column that is an identity and primary key. The second table contains two columns. One is a varchar primary key and the other is a nullable foreign key to the first table.
When adding the tables to the model I get the following validation error:
Condition cannot be specified for Column member 'DetailsControlSetId' because it is marked with a 'Computed' or 'Identity' StoreGeneratedPattern.
where 'DetailsControlSetId' is the second foreign key reference in the second table.
Steps to reproduce:
1) Create a new .Net 3.5 Client Profile project with Visual Studio 2010 RC.
2) Run scripts below against test database (empty database will do).
3) Create EDMX model, targeting the database created, but opt to not import any tables.
4) Update Model from Database selecting the two tables in the database (DetailsControlSet and Application).
5) Validate the EDMX model.
Table Creation Scripts:
CREATE TABLE [dbo].[DetailsControlSet](
[DetailsControlSetId] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_DetailsControlSet] PRIMARY KEY CLUSTERED
(
[DetailsControlSetId] ASC
)
)
GO
CREATE TABLE [dbo].[Application](
[ApplicationName] [varchar](50) NOT NULL,
[DetailsControlSetId] [int] NULL,
CONSTRAINT [PK_Application] PRIMARY KEY CLUSTERED
(
[ApplicationName] ASC
)
)
GO
ALTER TABLE [dbo].[Application] WITH CHECK ADD CONSTRAINT [FK_Application_DetailsControlSet] FOREIGN KEY([DetailsControlSetId])
REFERENCES [dbo].[DetailsControlSet] ([DetailsControlSetId])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Application] CHECK CONSTRAINT [FK_Application_DetailsControlSet]
GO
Update Now that you've (finally!) posted steps to reproduce this, I can make the error happen on my machine. And diffing the EDMX of the "import everything at first" vs. the "import tables later" models makes the problem obvious. The "working" model has this line:
<Property Name="DetailsControlSetId" Type="int" />
The "error" model has this line:
<Property Name="DetailsControlSetId" Type="int" StoreGeneratedPattern="Identity" />
That's the only substantive difference between the two models.
So to fix this:
Right click EDMX in Solution Explorer.
Open with XML editor.
Delete StoreGeneratedPattern="Identity"
Note that the error immediately goes away.
Having this test case, I was able to do some research. It turns out this is a known bug in VS 2010 beta and was fixed a few days ago.
This article might help, was posted at ADO.NET official team blog
Foreign Key Relationships in the
Entity Framework

Categories