Banging my head on this one. I'm trying to upgrade to Entity Framework Core 7. My class has a YearTerm and a CourseId. I can't get EF to use my key annotations or fluent API to identify my keys. I've tried the line below as in the Microsoft documents. It's a legacy table so I can't change it.
I've also tried removing the annotation and using Fluent API.
[PrimaryKey(nameof(YearTerm), nameof(CourseId))]
public class CourseInstance
{
[Column("YRTR")]
public string YearTerm { get; set; }
[Column("COU_ID")]
public string CourseId { get; set; }
.....
[ForeignKey("YearTerm")]
public YRTRCal YearTearmRecord { get; set; }
}
modelBuilder.Entity<CourseInstance>()
.HasKey(c => new { c.YearTerm, c.CourseId });
The error I get is :
Microsoft.Data.SqlClient.SqlException: 'Invalid column name 'CourseInstanceCourseId'.
Invalid column name 'CourseInstanceYearTerm'.'
I'm assuming it's not seeing my primary key columns, so it's trying to add them and of course they don't exist either in my table or in my model.
Any ideas?
Thanks;
Tried both the annotations and Fluent API and I expected it to work.
I've got a question. I have an existing mongodb collection I need to talk to containing an _id objectId and a UUID saved as string id field.
example
I need to fetch the documents based on a list of uuids -> which are basically the uuids in the id field of the document.
I've made a gateway to do this. (don't mind the TryAsync thingy that's basically a monad wrapped around a task)
public TryAsync<IEnumerable<T>> ByIds(List<Guid> ids)
{
var filter = Builders<T>.Filter.In("id", ids.Select(id => id.ToString()));
return TryAsync<IEnumerable<T>>.Apply(() => new List<T>()).SetAsync(() => Collection.Find(filter).ToListAsync());
}
The T is basically:
public interface IDomainObject
{
string id { get; set; }
}
When I run the code I get no result back.
So I decided to do some more testing, I've added the _id as well and tried to fetch it based on a fix _id.
Then I get this message =>
MongoDB.Bson.BsonSerializationException: 'The property 'Id' of type 'RG.Product.Core.Process.Product' cannot use element name '_id' because it is already being used by property '_id''
Seems like you can't have an _id and id on the same object?
I'm not interested in the _id object id, I just want to fetch the document without the _id field based on the id. Hopefully somebody can point me in the right direction?
Have a look at the attributes you can use in MongoDB.
public class DBInfo
{
[BsonId] // With this attribute you can define the _id field name
public ObjectId recordId;
[BsonIgnore]
public DBInfo child; // Ignore this variable
[BsonElement("sp")] // Rename this variable
public string searchPolicy;
[BsonExtraElements] // I always add this attribute on object with Id, this avoid deserialization exception in case of schema change
// All element the deserialization can't match will be added here
public BsonDocument catchAll;
}
https://github.com/iso8859/learn-mongodb-by-example/blob/main/dotnet/01%20-%20Begin/04%20-%20Attributes.cs
Using the latest efcore 2 preview from myget, it seems EF under certain conditions is not using the name of the DbSet<> property name as the table name. This is not exactly a simplified example...but this is the gist.
public class Post
{
public int Id { get; set; }
}
public class Context : DbContext
{
public DbSet<Post> Posts { get; set; }
}
In this case, I would expect the table generated to be called Posts... but instead it is using the singular version Post (the name of the entity).
There is no code inside the modelBuilder that is changing the pluralization or anything else that explicitly sets the table name.
Under what conditions would EFCore not default to using the DbSet property name as the table name? Has the default naming convention changed in efcore 2?
I'm getting this error on EF.
Cannot insert explicit value for identity column in table
'GroupMembers_New' when IDENTITY_INSERT is set to OFF.
The column on the Db is identity increment and on the EF design file, StoreGeneratedPattern is identity as well. Seems like EF is trying to insert 0 every time I try to save.
Some suggestions says ID is reserved on tables or drop the table and rerun the scripts.
Any ideas?
Here's some code:
GroupMember groupMember = new GroupMember();
groupMember.GroupId = group.Id;
groupMember.UserId = (new UserId(group.Owner));
//groupMember.Id = _groupContext.GroupMembers.Count();
group.GroupMembers.Add(groupMember);
_groupContext.SaveChanges();
I have run into this before. This error means you are trying to assign a value explicitly to a column where the database automatically assigns it.
Suggestion:
Update your edmx file to reflect any changes you may have made in the database.
If the database automatically assigns the value, you should see the "IsDbGenerated=true" attribute in your designer file under that property. If it's not there, you can add it manually.
Try this:
using System.ComponentModel.DataAnnotations.Schema;
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public decimal Identity_Col { get; set; }
The Entity Framework class file adds these lines of code to the Identity column.
Put these attribs on top of the property which is identity:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
I encountered the same problem and error message in my AspNetCore 2.x application.
The only way I could solve it was by removing this line in the ModelBuilder.Entity method of the DbContext class:
// remove: entity.Property(e => e.Id).ValueGeneratedNever();
EF Code first: Because of an auto-increment PK 'id' field AND a guid column, design like this:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid FileToken { get; set; }
there was a duplicate identity. I changed it to:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DefaultValue("newid()")]
public Guid FileToken { get; set; }
and the problem went away.
In EF 6, there is a property of the field/column in your model for doing this:
StoreGeneratedPattern.
Set this to "Identity" in the property dropdown list.
(I don't know about EF 4. The above answer, using IsDbGenerated, seems to be for EF 4.)
And this corresponds in the underlying XML to an attribute to the element:
<Property Name="MyTableId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
--but you don't need to deal with the XML manually, since you can use the designer.
How this gets messed up isn't clear. I had the problem even after refreshing my model from the database. Perhaps it gets confused if you set the PK on the table, or change its name, after you have already generated the model. (I am using the table/database-first approach, not code first.)
You can't use the above approach of putting the C# attribute on the entity code, because in this situation the entity code is generated by EF. EF is supposed to understand ("by itself") that the field is an identity.
I had this issue in my app; and got fixed it changing the property "StoredGeneratedPattern" of the id field to Identity.
So, Go to the model; look up for the table; click on propierties of the primary key fiel; and change the property.
See intercepting Entity Insert for generated always columns like StartTime and EndTime columns on history tables, rowversion columns as well.
I solved this by removing primary key in model from inserting data. because primary key auto increment.
var book = new Book
{
// Id = 1, //Don't need to write this
Genre = "Technology",
Author = "Charles Petzold",
Title = "Programming Windows 5th Edition",
Price = 30,
Publisher = "Microsoft Press"
};
_unitOfWork.Books.Add(book);
Well, You need give a value to ID, for example for the object Auto, just you should VarAuto.Id = 0;
After that you could do it something like this =>
using( MyContext db = new MyContext()){
db.Autos.Add(VarAuto);
db.SaveChanges();
}
That is the solution just give value to id, EF could be recognize the identity value in the table.
Just Try.
I'm using DB first and the table has identity column. I didn't use the db-scaffolding to generate this, I copied it from another entity and by mistake I took this property with.
So
Try to check the DBContext Class. I got this error, and the issue was with this property ".ValueGeneratedNever()"
I have just removed it and it works fine,
modelBuilder.Entity<TableName>(entity =>
{
entity.Property(e => e.Id)
//.ValueGeneratedNever()
.HasColumnName("ID");
});
Note: a moderator deleted this answer as a duplicate and left my other answer up, on a question with only the sql-server tag (which was the first question I arrived at from google). Since this question has the entity framework tag, posting the answer again here.
This is for EntityFramework Core 3.1.22. Using the wrong property to specify a foreign key causes Entity Framework to demote the primary key to ... something else. Entity Framework will then always attempt to insert an explicit value, which throws a database exception because it can't insert the value it's been told is a primary key and shouldn't be inserted.
Microsoft.EntityFrameworkCore.DbUpdateException: 'An error occurred while updating the entries. See the inner exception for details.'
Inner Exception:
SqlException: Cannot insert explicit value for identity column in table 'FOO' when IDENTITY_INSERT is set to OFF.
Code example. We have a 1-to-1 class mapping:
public class Foo /* child */
{
public int FooPrimaryKey { get; set; }
public int BarPrimaryKey { get; set; }
public virtual Bar PropertyBar {get; set; }
}
public class Bar
{
public int BarPrimaryKey { get; set; }
public virtual Foo PropertyFoo {get; set; }
}
modelBuilder.Entity<Foo>(entity =>
{
entity.HasKey(e => e.FooPrimaryKey);
entity.ToTable("FOO", "dbo");
entity.HasOne(d => d.PropertyBar)
.WithOne(x => x.PropertyFoo)
// wrong, this throws the above exception
.HasForeignKey<Bar>(x => x.BarPrimaryKey);
});
The foreign key should instead be (same key, different type):
.HasForeignKey<Foo>(x => x.BarPrimaryKey);
If you don't want to use EF core's auto-generating primary key values feature, you can turn it off. You can add your data to the primary key
It should resolve the error - Set Identity Insert off
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int StudentId { get; set; }
Setting Database Generation option to None helped me.
You can find more about it here- https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations
Add this line in order to allow the Id column to receive 1,2,3 and 4 values instead of being auto-numbered.
Sql("SET IDENTITY_INSERT MembershipTypes ON")
I have a problem while upserting to mongo db using the official C# driver.
public abstract class AggregateRoot
{
/// <summary>
/// All mongoDb documents must have an id, we specify it here
/// </summary>
protected AggregateRoot()
{
Id = ObjectId.GenerateNewId();
}
[BsonId]
public ObjectId Id { get; set; }
}
My entities already have the id-s but I had to create the mongo specific Id for it to work, as all the documents in a collection should have one. Now then I receive a new entity in my system a new Mongo Id is generated and I get the mongo cannot change _id of a document old exception. Is there some work-around?
Let me describe the design a bit. All the entities which would be
stored as documents were inheriting from AggregateRoot which had the
id generation in it. Every sub-document had its id generated
automatically and I had no problem with this. The id in AggregateRoot
was introduced to correct the problem when retrieving data from
MongoCollection to List and the generation was introduced so the id-s
are different. Now we can move that id generation to save methods
because the new entity for update had a new id generation. But it
would mean that every dev on the team must not forget generating id-s
in repository which is risky. It would be nicer just to ignore the id
than mapping from mongo if it is possible and not to have
AggregateRoot class at all
I've encountered similar problem.
I wanted to upsert documents using official C# driver. I had a class like this:
public class MyClass
{
public ObjectId Id { get; set; }
public int Field1 { get; set; }
public string Field2 { get; set; }
}
In console I would write: db.collection.update({Field1: 3},{Field1: 3, Field2: "value"}) and it would work. In C# I wrote:
collection.Update(Query.EQ("Field1", 3),
Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }),
UpdateFlags.Upsert);
and it didn't work! Because driver includes empty id in update statement and when I upsert second document with different value of Field1 exception E11000 duplicate key error index is thrown (in this case Mongo tries to insert a document with _id that already exists in db).
When I generated _id by myself (like topic starter) I've encountered the same exception (mongo cannot change _id of a document) on upserting objects with existing value of Field1.
Solution is to mark Id property by attribute [BsonIgnoreIfDefault] (and not initialize it). In this case driver omits _id field in update statement and MongoDb generates Id if it necessary.
Looks like you might be explicitly setting the Id value for both inserts and updates. That's fine for inserts, all new objects need an _id value, however for updates you're not allowed to change the value of _id on an existing document after it's created.
Try not setting the Id value at all. If you don't specify a value before inserting, the driver uses built-in IdGenerator classes to generate a new _id value, so if it's an ObjectId type it'll use the ObjectIdGenerator. Then both your inserts and updates work fine.