[DatabaseGenerated(DatabaseGeneratedOption.Identity)] - c#

I probably have spent 4 hours now and tried
Code First approach and
Database first approach
db.MoveJobs.Add(moveJob);
db.SaveChanges();
When a row is inserted it gives me
Cannot insert the value NULL into column 'id', table 'aspnet-AccountVerification.Web3.dbo.MoveJobs'; column does not allow nulls. INSERT fails.
The statement has been terminated.
public class MoveJob
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string CountryCode { get; set; }
public string PhoneNumber { get; set; }
}
Basically I need to generate incrementally a key for every itself for a new row. No Stack overflow / Forums / or something has helped.
I strangely worked yesterday though. I cant get where i went wrong

You don't need use [DatabaseGenerated(DatabaseGeneratedOption.Identity)].
The property id by default is key and identity. First remove this attribute and drop your database, after do this add a new migration.

Related

Cannot insert the value NULL into column 'Id', table '; column does not allow nulls

I'm seeing a strange behavior from Entity Framework. I'm using code-first approach to define a One-To-Many relationship between two entities:
public class IncomingCheck : AuditedEntityBase
{
[Key]
public int Id { get; set; }
[Required]
public virtual CheckType Type { get; set; }
[Required]
public virtual Bank Bank { get; set; }
public string Branch { get; set; }
public virtual IList<IncomingCheckHistory> History { get; set; }
}
public class IncomingCheckHistory
{
[Key]
public int Id { get; set; }
public string LongDescription { get; set; }
}
And here's I I'm trying to add an item to the History:
using (var db = new CheckDataContext())
{
foreach (var check in SelectedItems)
{
var dbCheck = await db.IncomingChecks.FindAsync(check.Id);
var history = new IncomingCheckHistory()
{
LongDescription = "something",
};
dbCheck.History.Add(history);
await db.SaveChangesAsync(); //throws the exception
}
}
But it throws an exception saying that "Cannot insert the value NULL into column 'Id'". However I've always done it like this. The database is supposed to fill the Id column itself with a unique number.
What am I missing?
Update:
Using SSProfiler, I got the query that runs on the database. It's as follows:
exec sp_executesql N'INSERT [dbo].[IncomingCheckHistories]([LongDescription], [IncomingCheck_Id])
VALUES (#0, #1)
SELECT [Id]
FROM [dbo].[IncomingCheckHistories]
WHERE ##ROWCOUNT > 0 AND [Id] = scope_identity()',N'#0 nvarchar(max) ,#1 int',#0=N'Something',#1=1
Note that scope_identity() should be getting the Id itself, correct?
Shouldn't the Id be set as the Identity?
Like this:
public class IncomingCheckHistory
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key]
public string LongDescription { get; set; }
}
Hope that this is the solution to your problem!
Well for some strange reason the exact code worked after completely deleting the database and migrations and starting from scratch. I'm not sure why it wouldn't work without migrations. Also I had tried deleting the database before but at the time I was trying a little different code.
In any case the posted code/query should work. Also I checked the database and the columns to see if anything is different and it wasn't. I would appreciate if someone could shed some light on why it wasn't working and it is now.

OrmLite Inserting 0 and instead of auto-incrementing primary key

I am trying to create a generic Insert<T> for our objects. I am new to OrmLite so I am still reading up on it. The objects that are used do not use an Id property they have a more detailed name.
As an example this a basic POCO:
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
...etc.
}
So the primary key is CustomerId and through some more reading I found that OrmLite likes to use the property Id for the primary keys. As we have a convention not to use just the name Id for the FK I cannot switch. However reading further it seemed like I could decorate the property with an attribute or two and get it to work.
This is what I am working with:
public class Customer
{
[AutoIncrement]
[Alias("CustomerId")]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
...
}
I get a SqlException stating the following:
Additional information: Cannot insert the value NULL into column 'CustomerId',
table 'XXX.dbo.Customer'; column does not allow nulls. INSERT fails
I did some more reading and thought I could fix the issue by inheriting from an interface.
public class Customer : IHasId<int>
{
[AutoIncrement]
[Alias("CustomerId")]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
...
}
I have played with using the PrimaryKey attribute and I still get the same result.
Has anyone had an issue like this? If you did how did you solve it? I am having a hard time finding some more information on the matter.
I can get rid of the attributes and name the property back to CustomerId so it matches the db table and it will insert into the table but it will always put in 0 as the key, which makes sense just because it is the default value for the int but does not help me when it has to be an autoincrementing primary key. As a side note I am using ServiceStack.OrmLite.SqlServer.3.9.71 and SQL Server 2008
UPDATE 1
So I went through the documentation again today for 3.9 version of ServiceStack.OrmLite and read through their description on what I should do when I don't have POCOs with an 'Id' property for the Primary Key. It is as follows:
... by convention OrmLite expects it to be Id although you can use [Alais("DbFieldName")] attribute to map it to a column with a different name or use the [PrimaryKey] attribute to tell OrmLite to use a different property for the primary key.
I used both of the examples and it does in fact insert my data to the SQLDatabase. However, it is still inserting 0 for the CustomerId primary key.
If I use the AutoIncrement attribute it throws a SqlException:
An exception of type 'System.Data.SqlClient.SqlException' occured in System.Data.dll but was not handled by user code. Additional Information: Cannot insert the value NULL into column 'CustomerId', table 'dbo.Customer'; column does not allow nulls. INSERT fails.
Has anyone run into this issue? I keep running into roadblocks.
i experimented the same issue. Your following code was already good.
public class Customer
{
[AutoIncrement]
[Alias("CustomerId")]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
...
}
The problem don't come from ORMLITE but from your database. Indeed, the column "CustomerId" which is i think the primary key for your table have his property "Identity" set to "False". You must set it to "True" or "Yes" and also set "Identity Increment" and "Identity Seed" to 1.
In v4.0.40, servicestack retrieves the primary key column by naming convention ("column_name" == OrmLiteConfig.IdField) as shown by the following code from OrmLiteConfigExtensions.cs:
internal static bool CheckForIdField(IEnumerable<PropertyInfo> objProperties)
{
// Not using Linq.Where() and manually iterating through objProperties just to avoid dependencies on System.Xml??
foreach (var objProperty in objProperties)
{
if (objProperty.Name != OrmLiteConfig.IdField) continue;
return true;
}
return false;
}
Therefore, using [AutoIncrement] with [Alias] should not work.

Db.SaveChanges Not Assigning Primary Key ID After Insert - Code First Entity Framework

I have a really weird situation with one class specifically. Upon adding the class to the DbContext to insert into the database and calling Db.SaveChanges code first/ef is not assigning the primary key id back to the class.
It's really odd, I've never encountered this before and I can't seem to find any solutions online.
Here is what the code looks like currently...
Invoice Code First Class
[Table("invoice")]
public class Invoice
{
[Key]
[Column("invoice_id")]
public int InvoiceId { get; set; }
[Column("invoice_credit_card_payment_id")]
public int InvoiceCreditCardPaymentId { get; set; }
[Column("batch_id")]
public int BatchId { get; set; }
[Column("customer_id")]
public int CustomerId { get; set; }
etc.....
}
Code to Insert Invoice into Database
var invoice = new Invoice()
{
BatchId = 0,
Memo = "",
PayDateTime = DateTime.Now,
QuickbooksAccountName = "",
QuickbooksId = "",
Terms = "",
etc....
};
DbContext.Current.Invoices.Add(invoice);
//Invoice record does insert successfully!
DbContext.Current.SaveChanges();
//This returns ZERO
var id = invoice.InvoiceId;
Additional Notes
As a side note the invoice record is successfully inserted into the database, however, the ID is not assigned back to the invoice object.
Another note - I have around 30 other code first classes that work just fine when doing inserts and getting ID's - it's just this one that is giving me issues for some weird reason.
Per jwatts1980 Recommendation
I updated the invoice class to reflect this
[Key]
[Column("invoice_id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int InvoiceId { get; set; }
This did not solve the problem immediately, however it did reveal a new error upon insert:
A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column: 'invoice_id'
I found a stackoverflow answer here which lead me to find some foreign key attributes I had setup on the invoice class:
[ForeignKey("InvoiceId")]
public ICollection<InvoiceOrder> InvoiceOrders { get; set; }
[ForeignKey("InvoiceId")]
public InvoiceCreditCardPayment InvoiceCreditCardPayment { get; set; }
Removing the ForeignKey attributes above seemed to solve the problem so far. I can't say that the it won't cause an other errors, however so far everything appears to be working well.
This attribute might help
[Key]
[Column("invoice_id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int InvoiceId { get; set; }

Entityframework Table name is appended with 'es' on savechanges

I'm facing a strange error using entityframe work. I have model entity called "UserInfo" and my DB table name is also "UserInfo". However when i'm called the savechanges() in entity frame work. i'm getting a strange error like Invalid object name 'dbo.UserInfoes'.
I searched the entire solution, to see whether i miss typed anything to "UserInfoes" and i didnt find anything. Please help me to solve this issue. How "es" is append along with it?
[Table("UserInfo")]
public class UserInfo
{
public int Id { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public int Field5 { get; set; }
}
You need to disable the Pluralize Table Names for the LINQ to SQL designer.
Here is the steps
http://msdn.microsoft.com/en-us/library/bb384507.aspx
It is probably to do with settings. EF will pluralise table names automatically under some circumstances. The problem may be your entity name: Userinfo -> Userinfoes. It looks like you are using code first so look at your entity settings.

EF Code First Auto generate column ID

I was wondering if it where at all possible to have a Key that auto generated like this:
CBE_2012_1
CBE_2012_2
CBE_2012_3
CBE_2013_1
CBE_2013_2
CBA_2013_1
CBA_2013_2
CBC_2013_1
I now have this in my class, with ID is Id with autonumbering:
[Key]
public int Id { get; set; }
public DateTime Date { get; set; }
public string Code { get; set; }
public string Name { get; set; }
But I would like to have this with Number being the KEY & format: Code_Year_Id:
[Key]
public string Number { get; set; }
public DateTime Date { get; set; }
public string Code { get; set; }
public string Name { get; set; }
Can anybody help me with this?
Or does anybody have helpfull documentation that can provide me with a decent solution?
Before I save a new item I could just create a number myself (In code), but there could be 2 people saving a new item # the same time and I do not want an exception on duplicate key..
Zarkos
Generally, using a meaningful value for a key is a bad idea. You will be much better off using a sequential value who's only purpose is to ensure referential integrity. If for not other reason than: if your key is not sequential, you are going to get a lot of fragmentation on your index as you insert new records.
If you do want to be sure that you get a unique value, you could create a SQL table that holds your last value, and then a UDF or sproc that takes the current value in that table, increments it to the next value and then returns that value.

Categories

Resources