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
Related
So i have 2 databases. DB1 and DB2. My 'discountCode' table is in DB1 and my 'AspnetUser' table is in DB2. I want to do a many to many table in DB1 between 'discountCode' table and 'AspnetUser' table so i can se that a user already have used a specific discountcode so the user cant use it twice.
I tried doing a normal many to many table between them and it went like this:
CREATE TABLE [dbo].[DiscountUser] (
[DiscountId] INT NOT NULL,
[UserId] nvarchar(128) NOT NULL,
[LanguageId] INT NOT NULL,
CONSTRAINT [PK_DiscountUser] PRIMARY KEY CLUSTERED ([DiscountId] ASC, [UserId] ASC),
CONSTRAINT [FK_DiscountUser_Discount_DiscountId] FOREIGN KEY ([DiscountId]) REFERENCES [dbo].[DiscountCode] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_DiscountUser_AspNetUsers_Id] FOREIGN KEY ([UserId]) REFERENCES [db2].dbo.[AspNetUsers] ([id]) ON DELETE CASCADE,
CONSTRAINT [FK_DiscountUser_Language] FOREIGN KEY ([LanguageId]) REFERENCES [dbo].[Language] ([Id])
I then want to update my entity framework modeldesign so i can include this new many to many table in my c# project. So it is important that however i fix this problem i will still be able to use this many to many table like any other entity i have.
First i thought that i would put all the tables in the same database untill i asked about this problem to a friend. My friend did not have much time. All he said to me was do a join in your c# code to bring the 2 tables together. Just ask stackoverflow and they will help you how. So here i am. How do i do a join in m y c# code or is there maybe a better way to get around my problem?
You can't have foreign keys between databases - the error is pretty clear about that. But you can still join them together in a query, you just won't get protection that having them joined by a foreign key gives (e.g. without a foreign key, you can end up with orphaned entries with no data in the foreign table).
If you can have them in a single database that would be best.
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.
I'm trying to create a table from within visual studio and update my .edmx file inside Visual Studio by right-clicking the file and selecting Update Model from Database.
My table looks like this:
CREATE TABLE [dbo].[tableName] (
[UserId] UNIQUEIDENTIFIER NOT NULL,
[CategoryId] INT NOT NULL,
CONSTRAINT [PK_responsibleUser] PRIMARY KEY NONCLUSTERED ([UserId], [pkID] ASC),
CONSTRAINT [FK_responsibleUser_user] FOREIGN KEY ([UserId]) REFERENCES [dbo].[users] ([UserId]) ON DELETE CASCADE,
CONSTRAINT [FK_categoryResponsibleUser_category] FOREIGN KEY ([CategoryId]) REFERENCES [dbo].[categories] ([CategoryId]) ON DELETE CASCADE
);
This table contains two foreign keys to the tables i want to link. After I run the script "Update Model from Database", a relation between the two tables pops up.
Now Heres the problem: I need EF to generate an instance of my class in Visual studio like this:
public virtual DbSet<tableName> TableIWantToBeGeneratedByEF { get; set; }
As I said, with the current mapping it just creates a relation between two tables. How do I alter my query when creating the table for this to happen? Can this be achieved while using two foreign keys as the primary key or what?
Just open the model designed, select all (ctrl + A), press 'delete' button to delete them, and finally right click and select Update Model from Database. This will force EF to re-generate all model.
(Or just delete all referenced tables so that they are also regenerated)
Almost forgot. It seems that it was the compound primary keys that caused the problem. I changed so both my foreign keys just acted like foreign keys and not as a combined primary key, then created a columnn named Id instead with datatype INT Identity.
Ran the script "Update Model from Database" in .edmx designer and boom, there it was.
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?
I am trying to do a one to one join with 2 tables using non-primary fields.
I have 2 tables in the DB.
CREATE TABLE [dbo].[Branch](
[BranchID] [int] IDENTITY(1,1) NOT NULL,
[Branch_Name] [nvarchar](100) NULL)
CREATE TABLE [dbo].[Salesman](
[SalesmanID] [int] IDENTITY(1,1) NOT NULL,
[BranchID] [int] NOT NULL,
[First_Name] [nvarchar](30) NULL,
[Last_Name] [nvarchar](30) NULL)
I basically need the Branch Name whenever I retrieve a row from the salesman table.
I thought I could add a join in the Salesman.hbm.xml file.
<join table="dbo.Branch">
<key column="BranchID" />
<property lazy="true" update="false" insert="false" not-null="false" type="String" name="Branch_Name" />
</join>
This did not work because nHibernate always created a join with the primary key. I read some other posts and they suggested using a view for situations like this. So I created a view like so:
create view dbo.VIEW_Salesman As
SELECT a.[SalesmanID], a.[BranchID], a.[First_Name],a.[Last_Name],
(select [Branch_Name] FROM [dbo].[Branch] WHERE BranchID= a.[BranchID]) As Branch_Name
FROM [dbo].[Salesman] as a
The above view actually works but is there a better solution when you want to join 2 tables using non-primary fields?
Thanks in advance for any suggestions and advice,
Have a great day!
You could either use Dependancy Injection which actually has nothing to do with NHibernate, and would definitely force a change in your mapping file, or perhaps use a named query in the NHibernate configuration file.
Besides, I just thought that you perhaps could use composite mapping while using Dependancy Injection.
Salesman s = new Salesman(branchInstance)
So you should have a Branch property within your Salesman class that could allow you to know the branch name to which this salesman belongs. Otherwise, simply have a BranchName property which would actually return the branchInstance.Name property value.
See the following for Component Mapping using NHibernate:
NHibernate Mapping - ;
NHibernate - Chapter 7 - Component Mapping;
NHibernate Reference Documentation.
Or if you prefer to make it as a view using NHibernate, perhaps a named query should do it with less of a change:
16.2. Named SQL queries.
Hope this helps! Do not hesitate to ask further details, I'll be pleased to assist you furhter if I can! =)