Duplicate 'System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute' attribute - c#

I am using EntityFramework version 4.4, code first and I have created my data model in a separate project (MyApp.DataModel).
Because I am building a Silverlight application, I am using a WCF RIA services. The code required by the ria services is in a different project (MyApp.Services). This project has a reference to MyApp.DataModel.
An example of an data model:
[Column("Remaining")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual decimal? Remaining
{
//
}
When I build MyApp.Services I get an error
Duplicate 'System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute' attribute
Indeed, in the generated code there are two attributes
[System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed)]
[System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed)]
If I remove DatabaseGenerated, then on insert I get an error
The column "Remaining" cannot be modified because it is either a computed column or is the result of a UNION operator.
Any idea why and how to solve this problem?

As far as I understand the documentation here: http://msdn.microsoft.com/en-us/data/gg193958.aspx , Key already defaults to DatabaseGeneratedOption.Identity, so you wouldn't need to add the DatabaseGenerated separately.
Excerpt from the part under DatabaseGenerated:
a key property will become an identity key in the database. That would
be the same as setting DatabaseGenerated to
DatabaseGenerationOption.Identity. If you do not want it to be an
identity key, you can set the value to DatabaseGenerationOption.None.
To be honest, I haven't tested this, but can you confirm that after removing [DatabaseGenerated(DatabaseGeneratedOption.Identity)] , the other attribute still remains in the generated code?

If you mark the property as DatabaseGeneratedOption.Identity the EF understand that this is the key attribute.
Actually if you don't place none attribute (Key or DatabaseGeneratedOption.Identity) the EF will assume that this is the id as the property ends with 'ID' and will create a autoincrement field at database.
The DataAnnotations are optional in many cases (like yours).
You also don't need to mark this property as virtual as it's a primitive type. Use virtual just to associate others classes (lazy load).

Related

Dapper returns SQL conversion error on ID column

In my database I have an ID column that is a nvarchar type because it contains unique user names. In my .Net MVC application I am using Dapper to handle the database exchange. I then use the DapperExtensions.Get(dynamic id) on my models to grab a specific entry by the ID field. This works great in all cases except in users where I get the following error:
Conversion failed when converting the nvarchar value 'abcdefg' to data type int.'
I know that this is the ID column because that value exists in the ID property of my User model when it is used to extract the entity using Dapper. My best guess is that maybe Dapper expects that the dynamic id argument would be an int and tries to use it as such. I'm hoping to get some clarification on this by someone who understands it better than myself.
I have made sure that my database table uses nvarchar for this field and it is marked as the Primary Key.
Thanks
Make sure to use Dapper.Contrib.Extensions.Key attribute to flag the correct property as the Key property. Do not use System.ComponentModel.DataAnnotations.Key as it may act differently.
However, sometimes, this is known to not work. When no Key attribute is present, try putting the field to the top of your class and DapperExtensions may treat this as your Primary Key.
Or try using ExplicitKey?
I figured out the answer right after posting the question by running a sql profiler on the application. The solution is quite a stupid one.
Using the profiler, I could see that the sql command created by Dapper was attempting to match the nvarchar against a different column that was indeed an integer column. I then looked at my User model and noticed that this column shows up as the first property declared in this model.
The solution was to move the ID property to be the first declared property and then everything worked fine. Apparently Dapper just uses the first declared property within a model as the ID column despite which property might have the [Key] attribute tag on it.

EntityFramework code first: Set order of fields

I am using EntityFramework with the "Code first" approach with migrations.
I have successfully generated tables from my models, but the columns are being added in an alphabetical order rather than the order inside my model.
I have tried this:
[Key, Column(Order=0)]
public int MyFirstKeyProperty { get; set; }
[Column(Order=1)]
public int MySecondKeyProperty { get; set; }
But that doesn't seem to be working.
How can I manually set the order of the fields in the database?
I am using ASP.NET Core and EF Core (SqlServer) v1.1.0.
Currently ordering columns by class property is not implemented.
Here's the long discussion about column ordering. Column ordering #2272
Update as of 07/12/2017
This issue is in the Backlog milestone. This means that it is not
going to happen for the 2.0 release. We will re-assess the backlog
following the 2.0 release and consider this item at that time.
Update as of 06/10/2019
Issue 2272 shipped with EF Core v2.1 and matches the order of the columns in the generated table to the order of the properties in the class. However, as #lloyd-conrade mentioned, this is only useful for initial creation
A new issue, #10059, has been created to track the possible implementation of respecting the Column attribute's Order property.
If the implementation of #2272 is insufficient for you and specifying something
like [Column(Order = 1)] would help, please vote for this issue and add details
about your scenario (if not already listed) below.
Note the "Punted for 3.0" label was added on May 10th, 2019, which is to say it will not ship in EF Core 3.0.
Update: In EF Core 2.1, for the initial migration at least, columns are added to tables in the order in which the relevant properties are declared in their respective classes, rather than in alphabetical order. See here. But note that any subsequent Entity Framework migrations performed on the same tables won't change the column order of the columns created earlier.
At this moment EF core doesn't support it.But there is a workaround for that.That is, you can explicitly specify SQL on your migration operation.
Instead of using the CreateTable method in your migrations, you need to explicitly write the SQL as shown below.There you can give the order as you wish.
migrationBuilder.Sql("CREATE TABLE Properties(
MyFirstKeyProperty INT NOT NULL,
MySecondKeyProperty int NOT NULL,
AGE INT NOT NULL,
......
......
PRIMARY KEY (MyFirstKeyProperty)
)");
You can read about the rowanmiller's commnet here about how to sort out that issue just for now
You can use this solution to add support for explicit column ordering to your project: https://github.com/premchandrasingh/EFCoreColumnOrder. This solution adds the HasColumnOrder extension method. There is an example of use in the Sample folder. Do not forget to replace the corresponding services in your DbContext.
the order of the columns you mention is used to specify the order of the columns a compound foreign key, as it is in the case of some tables that have two or more fields as foreign key that refer to other tables, in that case you can use Column (Order = n)
As of Entity Framework Core 6 you can specify the column order with an annotation:
[Column(Order = 1)]
public int Id { get; set; }
https://learn.microsoft.com/en-us/ef/core/modeling/entity-properties?tabs=data-annotations%2Cwithout-nrt#column-order

The item with identity [x] already exists in the metadata collection. How do I fix that?

I'm using Entity Framework 6, with POCO and fluent-API and I've noticed an annoying bug.
If I have an entity called MyEntity and this entity has a property called MyProp, that makes it impossible to create an entity called MyEntity_MyProp.
Exception:
The item with identity 'MyEntity_MyProp' already exists in the metadata collection.\r\nParameter name: item
The error immediately goes away if I rename any of the entities, or rename the properties.
The "bug" is obvious: the key [EntityName]_[PropertyName] must be unique in the metadata collection.
Screenshot:
I'm migrating a huge Entity Framework model with 390+ classes from EF 4, database first, to EF 6, code first, with fluent-API. It's out of question to rename the entities or the tables.
How do I solve that?
EDIT
This SO question doesn't have anything to do with my problem: The item with identity 'Id' already exists in the metadata collection. Parameter name: item
This bug happens when you use underscores in the name of your entities. The reason is Entity Framework also uses underscores to create the names of the keys (concatenating the entity and property names).
So, if you have an entity named "Table" with a property "Prop" and a table named "Table_Prop" a clash will occur. This is most likely what happened.
It's a known bug. It's currently scheduled to be fixed in an arbitrary future version, that is, it's not in the road-map yet.
Source: https://entityframework.codeplex.com/workitem/2084
EDIT:
According to #Anthony, this was fixed in v6.1.3
I was able to work around this by adding the Table attribute on the EF table object, and then renaming the object to something like MyEntityMyProp. I then refactored by code to use the new object name. This was more simple than renaming the database table.
[Table("MyEntity_MyProp")]
public class MyEntityMyProp
{
...
}
Please check ApplicationDbContext in your project.
maybe your entity name used as the property name in public DbSet<>.

Entity Framework 5 Key naming with code first

I can't have [.] (periods) in my key names (Indexes, primary keys and foreign keys) when they are generated by Add-Migration, so I tried to write a CSharpMigrationCodeGenerator, but unfortunately this doesn't seem to allow you to change the foreign keys or index names. The primary key name can be set as part of overriding the create table:
protected override void Generate(
CreateTableOperation createTableOperation, IndentedTextWriter writer)
{
createTableOperation.PrimaryKey.Name = "USE THIS NAME";
base.Generate(createTableOperation, writer);
}
But what I really need is a way to ensure that it has just removed full stop (which implies overriding the custom name generator) - but I can't see how to do this.
Have you not tried retrospectively generating code first with the power tools?
Not only would it generate code first classes for you from the database, you can also customize the T4 templates that generate your objects in order to handle unique scenarios (for example custom naming logic to handle reserved characters). My entity.tt has the following above each generated object:-
[MetadataType(typeof(<#= efHost.EntityType.Name #>_Validation))]
This means I can have all my data validation farmed off into a separate class that isn't overridden upon re-creation of my objects.
this issue no longer exists and was quite specific at the time. Things have moved on with tooling over the last year and therefore isn't really relevant anymore as you wouldn't need to solve the issue this way.
Many thanks for reading and commenting
by entity framework code first migration you can change the foreign keys or index names, you can see in the example in here:
http://msdn.microsoft.com/en-us/data/jj591621.aspx
http://www.dotnetcurry.com/showarticle.aspx?ID=889

Removing navigation properties from POCO-classes in Entity Framwork

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.

Categories