EF6 Unrecognized Guid format. while trying to find in set - c#

I'm facing problem with 'Unrecognized Guid format.' while trying to find the data in the set.
Application work with .Net 4.5 and EF6. I'm facing this issue since we switch from MsSql to MySql Db.
Entities look like:
public abstract class DomainEntity(){
public Guid Id { get; protected set; };
public bool IsActive { get; protected set; }
public DateTime CreateTime { get; set; }
public DateTime ModifyTime { get; set; }
}
The DB tables look like:
CREATE TABLE IF NOT EXISTS `MssDocumentsDb`.`dbo_Versionings` (
`Id` CHAR(36) UNIQUE NOT NULL,
`IsActive` TINYINT(1) NOT NULL DEFAULT 1,
`CreateTime` DATETIME(6) NOT NULL,
`ModifyTime` DATETIME(6) NOT NULL,
PRIMARY KEY (`Id`));
And getting most data working properly, but sometimes I'm facing the issue with 'Unrecognized Guid format.'
The places where mostly that error occurs looks like:
public virtual TEntity Get(Guid Id)
=> Id != Guid.Empty ? GetSet().Find(Id) : null;
Create set:
public IDbSet<TEntity> CreateSet<TEntity>()
where TEntity : class => base.Set<TEntity>();
I'm tried different solutions to solve this issue.
Tried to switch Id in db from CHAR(36) to varchar(64), passing Id.ToSting() or adding 'Old Guids=true' to the connection string, but without results.
Thanks for any help.

Many thanks to #mjwills for the help with figuring out what's going wrong.
My main issue was the data of Ids. Some Ids after migrating from MsSql to Mysql were imported as an empty string otherwise in mssql they were stored as null. After updating data for ids (set null where id = '') all work properly.

Check your entire row record if contains another guid columns which are empty. Sadly the error is not very informative, for example which column is empty but it is supposed to be a guid.

Related

SQLite seems to have a problem with [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

I have a problem with the SQLite in-memory database. The normal database is working.
This is my model code
public class Log
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string Message { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime CreatedAt { get; set; }
}
The SQL statement to create the table
CREATE TABLE [dbo].[AuditLogs]
(
[Id] UNIQUEIDENTIFIER NOT NULL DEFAULT newid() PRIMARY KEY,
[Message] varchar(max) NOT NULL CONSTRAINT ensure_json CHECK (ISJSON([Message])> 0),
[CreatedAt] datetime NOT NULL default GetDate()
)
The error
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'NOT NULL constraint failed: AuditLogs.CreatedAt'.
Do you have any solution?
You could just use this:
public Guid Id { get; set; } = Guid.NewGuid();
The problem with the Entity Framework is that it won't generate keys for you. If it is database-generated then some trigger in the database would still need to create this ID. This is generally done when the ID is of type int, but not Guid. Then again, SQLite is a weird database provider to begin with as it doesn't really has datatypes. Data type definitions are more suggestions and not enforced by the engine. (But EF will enforce it.)
Anyways, since you use Guids there's nothing wrong with assigning new values to the property, as they will be overwritten by the value in the database on retrieval. But SQLite isn't really generating values for you.
Also, I would use public DateTime CreatedAt { get; set; } = DateTime.Now(); for the same reason. I myself actually had similar problems but I use the Fluid API instead and use this:
var hostBuilder = modelBuilder.Entity<Host>();
hostBuilder
.Property(r => r.Id)
.HasColumnOrder(0)
.IsRequired()
.HasColumnName("Key")
.HasColumnType("varchar(36)")
.HasComment($"Primary key");
hostBuilder
.Property<DateTime>("Created")
.HasColumnOrder(1)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.ValueGeneratedOnAdd()
.HasComment($"When was it created?");
hostBuilder
.HasKey(r => r.Id)
.HasName($"PK_Visitor_Host_Key");
And my class only has the Id property defined, as I don't need the Created field in my project. It still gets added, though! The HasDefaultValueSql() call will tell that the field is database-generated, including how it's generated. You might want to look into this Fluid API for your project. I prefer it over those attributes as it provides more options and better control, plus I can add fields to tables that are not important for my code, yet still required for other purposes...
(Btw. You don't want timestamps to be unique as two records could be created at exactly the same timestamp on fast systems.)

Cannot insert the value NULL into column 'MaintenanceId', table '<tableName>'; column does not allow nulls. INSERT fails EF 6.1

So i'm trying to do a simple add an entry to my db on azure but for some reason the db is not generating my PK for the entry.
Below is all the code used to create the db and do the entry.
This is on EF 6.1 on a console app
Context
public BlizzardDbContext() : base("AzureSqlDb")
{
}
public DbSet<Maintenance> Maintenances { get; set; }
Model
public class Maintenance
{
public Maintenance()
{}
public Maintenance(DateTime start, DateTime end, string info)
{
Start = start;
End = end;
Info = info;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int MaintenanceId { get; set; }
public DateTime? Start { get; set; }
public DateTime? End { get; set; }
public string Info { get; set; }
}
Test that failed on save changes
var context = new BlizzardDbContext();
context.Maintenances.Add(new Maintenance() {Start = DateTime.Now, End = DateTime.Now, Info = ""});
context.SaveChanges();
I know it sounds so simple, i've used EF a few times before but cannot figure out what is going wrong this time
and here's the error
"Cannot insert the value NULL into column 'MaintenanceId', table '.dbo.Maintenances'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."
Update: Ended up fixing this by deleting the db and recreating it, I think there was something weird going on with EF, it wasn't updating the db with the migration properly since after recreating it the column was then set to be Identity
Just verify whether the MaintenanceId is identity key or not in DB.
If it is not or you are not sure you can try below option
change
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
to
[DatabaseGenerated(DatabaseGeneratedOption.None)]
.None - That means "The database does not generate values."
Log on to your database and verify that the MaintenanceId is indeed auto-generating the key. EF supports this, and I suspect that something fun happened during migration, if you used that, or during the construction of the table.
Also, make sure that you have not disabled tracking of objects in your DbContext class. It is default on, so unless you explicitly disabled it, you do not have to worry about that one :)

Can't insert the value NULL into column in EF 6.1.3

I created a table in SQL Server Management Studio with two columns, FacilityId is the primary key and not null. After the design, I manually added the first row.
However when I insert the new record into the table programmatically in C# code I get this error:
Cannot insert the value NULL into column 'FacilityId', table 'xxxxxxxx'; column does not allow nulls.
My table in code:
public class MyURL
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Column("FacilityId")]
public int FacilityId { get; set; }
[Column("Url")]
public string Url { get; set; }
}
To add new record by the below code:
public void AddNewUrl(int id, string url)
{
using (MyUrlContext context = new MyUrlContext())
{
context.Database.Connection.ConnectionString = GetConnectionString(context);
var data = GetNewUrl(id, url);
SaveContextAfterAddingNewRecord(context, data);
}
}
public virtual void SaveContextAfterAddingNewRecord(MyUrlContext context, MyURL data)
{
context.MyEndpoints.Add(data);
context.SaveChanges();
}
And
public class MyUrlContext : DbContext
{
public MyUrlContext():base()
{
Database.SetInitializer<MyUrlContext>(null);
}
public DbSet<MyURL> MyEndpoints { get; set; }
}
So what is wrong?
EDIT:
The db/table structure.
Also, I do have the value provided.
See the image:
I am sure that the identity property is off.
EDIT2:
The SS profiler indicated
exec sp_executesql N'INSERT [dbo].[TableName]([Url])
VALUES (#0)
SELECT [FacilityID]
FROM [dbo].[TableName]
WHERE ##ROWCOUNT > 0 AND [FacilityID] = scope_identity()',N'#0 nvarchar(max) ',#0=N'sdfsdf'
What's the exact definition of FacilityID in your database table?
Is it defined as an IDENTITY column (to make SQL Server assign values automatically)?
If so, then you need to use [DatabaseGenerated(DatabaseGeneratedOption.Identity)] in your EF model.
If it's not defined as an identity column, then you must provide a value when you insert a new row.
Update: if that column is not an identity column (which seems to be the case), I'd recommend to entirely remove that [DatabaseGenerated(DatabaseGeneratedOption.None)] attribute from your model class:
public class MyURL
{
[Key]
[Column("FacilityId")]
public int FacilityId { get; set; }
[Column("Url")]
public string Url { get; set; }
}
Finally reslove it under the help of somebody in the team. The code itself is nothing wrong. The problem is that I developed the project as a class library and add it to an asp.net MVC application. The web application is a DNX 4.5.1 project. Because my original dll had some defect I believe, although I updated it, the DNX 4.5.1 framework couldn't find it. It always looked the original dll in the cache.
The right action is to push the dll to the Nuget server, then add to the web application. So the dll version can be incremented automatically.
So whatever I played the attribute, it just is not working. Hopefully in the next release of Visual Studio 2015 release, the issue can be resloved.

EF6 Code First Mapping where key name is different in DB

I am trying to do a "code first" EF model based off an existing db (which I recognize immediately is counter to the concept of an EF code-first approach), but I keep running into a problem, and the error message does not make sense to me, so I'm hoping for some insight.
My table is defined like so:
CREATE TABLE [dbo].[BackupLocales]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[LocaleId] INT NOT NULL constraint fkBackupLocales_Locale references dbo.Locales(Id),
[BackupLocaleId] INT NOT NULL constraint fxBackupLocales_BackupLocale references dbo.Locales(Id),
[Weight] INT NOT NULL DEFAULT 1
)
go
create unique nonclustered index uxBackupLocales_Locale_Weight on dbo.BackupLocales(LocaleId, [Weight]);
In code, I wrote the following entity class:
public class BackupLocale
{
[Key]
[Column("Id")]
public Guid Id { get; set; }
public int Weight { get; set; }
[Column("LocaleId")]
public int PrimaryId { get; set; }
[ForeignKey("PrimaryId")]
public virtual Locale Primary { get; set; }
[Column("BackupLocaleId")]
public int BackupId { get; set; }
[ForeignKey("BackupId")]
public virtual Locale Backup { get; set; }
}
... which, as far as I can tell (based off of the samples and documentation I've read), look correct. The only "weirdness", as far as I can see, is the fact that the column name for the Primary locale is different in the database; I wanted to make it more specific in code than it is in the table.
Naturally, this does not work when trying to load the entity model (or else why would I be asking a question? :) )
I get a rather long error message, but the heart of it would be this part:
System.Data.Entity.Core.EntityCommandExecutionException: An error
occurred while executing the command definition. See the inner
exception for details. ---> System.Data.SqlClient.SqlException: Invalid
column name 'LocaleId'.
The problem here is, if I were not using EF, a SqlClient.SqlException with the message "Invalid column name 'LocaleId'" would mean that the column literally did not exist in the SQL server... but that is definitely not the case here. It does exist... so I'm not sure what's going on here. The only thing I can figure is the fact that I am changing the name of the property is somehow screwing up the mapping, but of course it could be that I'm just doing something dumb.
Have I misunderstood how the attributes are supposed to work? Have I configured this incorrectly? Or am I trying to do something that is not supported in EF6?
It looks like this was a Visual Studio problem. I closed the solution, exited VS, restarted VS, and loaded the project, and it started working. :(

Cannot insert the value NULL into column in ASP.NET MVC Entity Framework

When trying to use this code:
var model = new MasterEntities();
var customer = new Customers();
customer.Sessionid = 25641;
model.Customers.Add(customer);
model.SaveChanges();
I get:
{"Cannot insert the value NULL into column 'Sessionid', table
'master.dbo.Column'; column does not allow nulls. INSERT
fails.\r\nThe statement has been terminated."}
The column "Sessionid" is actually the primary key and is marked with [KEY] like this:
public class Customers
{
[Key]
public long Sessionid { get; set; }
public long? Pers { get; set; }
}
So according to this question, it seems as if when the property is marked with [KEY], EF ignores my own declaration of Sessionid since it expects the database to assign the value.
So how can I solve this? If I remove [KEY] I get the "entity type has no key defined" exception...
I solved it by adding [DatabaseGenerated(DatabaseGeneratedOption.None)] like this:
public class Customers
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Sessionid { get; set; }
public long? Pers { get; set; }
}
You can configure SQL to auto-generate (and auto-increment) the primary key for the table upon inserts. Then just remove the [Key] in C# and you don't need to set the ID in the application manually, the db will generate it for you.
I have encountered this problem multiple times while working with Microsoft SQL Server and I have followed the same way to fix it. To solve this problem, make sure Identity Specification is set to Yes. Here's how it looks like:
In this way the column number auto increments as a primary key normally would.
HOW?: right-click the table that contains the column, choose Design, select the primary key and in Column Properties window find Identity Specification and set it to Yes.

Categories

Resources