I'm having troubles when I do a POST endpoint.
When I run the code to insert data into my database, it breaks because of an invalid column name; I'm inserting the class entity that has an extra property (that is always null, except when I'm bringing it from another table with an inner join). This property is read as a column from the entity that I'm trying to insert and it breaks.
There is a way to ignore this property? I'm not using Entity Framework, I've tried a few ways already. That is why I'm asking.
EDIT: I'm having these error for INSERTS and UPDATES because I'm saving the entity that has 1 extra property that doesn't match with the table. My question is, there is any way to ignore it for these cases?
await _clientRepository.UpdateAsync(client);-> this line breaks because client.Description doesn't exists in the sql table.
[NotMapped] -> didn't work.
Related
I have two entities one of them paper and the other one is paper line.
I am using SQL Server to store the entity records, each entity is represented by a table in the database
PaperEntity contains columns
Id, Color, TimeStamp (RowVersion), etc...
PaperLineEntity contains columns
Id, PaperId(FK), lineContent, TimeStamp (RowVersion), etc...
I am thinking about how can I prevent two users to update two different lines in the same paper, my idea is when you update the line you have to update the timestamp for the paper record that this line belongs to it, any ideas on how can I manage that in EF Core?
When fetch lines of Paper, get TimeStamp(RowVersion) too,
When user save the line,
first compare timestamp
if it is different, so you return an error else it is same, then you Allow update it
You can use concurrency tokens. Idea is the same as you described: you have a special property which is updated together with each update of entity. You should mark this property using special attribute or using fluent configuration. EF Core will compare old_value (initially read from db) and current_value (currently presented in database) automatically during each update. If they are not equal special exception will be thrown.
I am trying to understand the (functional) difference between the two DatabaseGeneratedOption's in Entity Framework (code first):
DatabaseGeneratedOption.Identity
DatebaseGeneratedOption.Computed
I have read the documentation, but I do not understand the functional difference between the two.
The option Identity is described as The database generates a value when a row is inserted. But I cannot update the value later if I try I get an exception saying that I cannot modify a column with Identity pattern.
The option Computed is described as The database generates a value when a row is inserted or updated. However, this is just what you tell Entity Framework, so far I have not been able to achieve this, without SQL triggers. If I try to update the value, nothing happens (Entity Framework refuses to overwrite the existing value).
So what I am left with, is two functionally identical options. I can have a default value in my SQL table, which will be applied on the insert. And I cannot update this value afterward (using Entity Framework). So where in lies the difference in how they should be used?
A computed column contains a value that is computed (hence the name) when the record is requested.
A computed column can be composed of other column values, constants and function return values.
You could for example create a computed column for an invoice expiry date:
CREATE TABLE Invoice
(
InvoiceDate DATETIME NOT NULL,
ExpiryDate AS DATEADD(DAY, 30, InvoiceDate)
)
Now if you mark this column as computed in Entity Framework, it will refuse any updates to that column, because it'll know the database won't support that.
So the documentation for that attribute is incorrect or incomplete.
A column marked as Identity will use the database-specific syntax to generate a primary key for the given table when inserting a record, being IDENTITY() in MSSQL and AUTO_INCREMENT for MySQL. A computed column will simply be marked as read-only, and you'll have to provide your own implementation (either in the database or in your migration file) to specify the computation (see How to add computed column using migrations in code first?).
I am using EF 4.0 and I have in my database a table with a timestamp field because I want to control the concurrency in this table.
Then, I created my edmx and I generated the POCO classes with the template DBContext.
The first try that I do is, in the edmx, in the timestamp field, I set stored generated pattern to none. Then in my code I do:
myContext.MyTable.Attach(myEntity);
myContext.Entry<MyTable>(myEntity).Property(p => p.AnyFieldNoTimestamp).IsModified = true;
myContext.SaveChanges();
This give me an exception that says that is not possible to update a timestamp column.
If I have I only marked a field to modified, and this field is not the timestamp, why I get this error?
Then I try to set the propery stored generated pattern in the edmx to Indentity.
really I have a transaction and two saveChanges. In this second try, the first savechanges does not give any error but in the second savechanges I get the excepcion 0 rows affected, because it seem that the timestamp of the entity has changed from the first savechanges to the second, so in the concurrency control I get this excepction.
So I would like to know how can I use a timestamp field inside a transaction and two save chages.
Thanks.
I try to use the set Computed and in this case works correctly.
I have a problem in Linq. I am getting all the contents a in table when I query. But I don't want to load certain rows which are marked with some special key Y.
So, for this, I'm iterating and removing from my local copy those which are having special key Y.
Later on, when I submit changes, I get an error:
"An attempt was made to remove a relationship between a priceTable and a dataTable. However, one of the relationship's foreign keys (P.Id) cannot be set to null."
Why is it so? How can I alter the contents of a particular entity set without touching some of the rows?
I want the rows that are marked as Y not to be returned from the DB. I don't want use them in my c# at runtime.
Dennis is correct. If you don't required those records marked as 'Y', then use the where clause and exclude those records. Then you are free to modify and update the records back to the database without any issues.
sample where clause looks like below
var data = from p in context.Persons
where p.Required == "Y"
select p;
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?