InvalidOperationException You must set this property to a non-null value of type string - entity-framework

The XX property on 'Table' could not be set to a 'Byte[]' value. You must set this property to a non-null value of type 'String'.
I didn't create the mapping myself, this was generated from a db first scenario. I am not inserting anything to a table, I'm just performing a select, this shouldn't happen at all? Why am I getting this error and how do I fix it?

I had a similar issue but for byte to bool
I edited my entity
public byte XX { get; set; }
Then edited my Model to have
public bool XX { get; set; }
used auto mapper to map them together and it fixed the issue i was having, try this with editing your Model to a string and map it accordingly.
i am using code first for my existing databases, but it may work for db first

Related

Entity Framework Core 6 - System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values

I'm using EF Core 6 on .NET 6.0 and am looking at this error:
System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values
The error message should indicate that EF Core is trying to read a value for a required property, i.e. a property which should never have null value in the database, but instead the underlying data reader reports null value for that property in some record(s).
Entity Framework Core: `SqlNullValueException: Data is Null.` How to troubleshoot?
Disabling nullable reference type the error disappears and everything works well.
Is it possible to investigate exactly what field is causing this issue, debugging the code doesn't give me more details.
Is there some technique to get the name of the offending field or fields?
Visually I didn't find any discrepancy between the database and the model
Check the document related with Nullable reference types
In a nullable aware context:
A variable of a reference type T must be initialized with non-null,
and may never be assigned a value that may be null.
A variable of areference type T? may be initialized with null or
assigned null, but is required to be checked against null before
de-referencing.
assuming an entity:
public class SomeEntity   
{   
[Key]     
public int Id { get; set; }       
  public string Name { get; set; }        
public string Prop { get; set; }    
}
If you enabled nullable reference type, Name and Prop property would never be assigned with null
Assuming the Db:
When you read data from db and assign the null value in db to your entity,you would get the error you've shown
Is it possible to investigate exactly what field is causing this issue
All properties type of T instead of T? in your entity with the column could be null in db would cause this issue
Both Disabling nullable reference type and Setting your property which may have null value in db with T? would solve the issue.
For example,in my case,the Name column and Prop column could be null in db,when you check your entity, Name and Prop property should be type of string? instead of string .
yes, this is the cause.
But my question (maybe is not so clear, it's my falut) is about how to get some sort of notification from the debbugger, the call stack, or from a verbose output, an indicatin of what field has null value
It's not so easy to verify manually because my entity are a customization of a the aspnet identity database
E.G: calling _userManager.FindByNameAsync i got this error
Apparently i've filled all nullable values but maybe the error is caused by other related entity e.g Roles, Claims, and so on
So i'd like to get a clear indication about what is the first field(if there are more) that has caused the problem.
If possible of course!

Entity Framework 7 Fluent API Doesn't Recognize IsOptional()

I'm currently setting up my database in my Asp.Net 5 project using entity framework 7, previously with EF 6, when I wanted to make some of my columns nullable, I would use:
modelBuilder.Entity<Article>().Property(t => t.ArticleDateModified).IsOptional();
But it seems that IsOptional is not part of EF7 anymore, I was wondering how can I achieve the same thing using EF7?
Edit:
Marc's answer is indeed correct, first I though it worked because I found something that was like IsOptional:
builder.Entity<Article>().Property(t => t.ArticleDateModified).IsRequired(false);
But after I ran some test without it, it set the database column nullable because I marked it as nullable in my domain model:
public DateTime? ArticleDateModified { get; set; }
Also worth to note that when I made the DateTime non-nullable and used the IsRequired(false), I got the following error:
The property 'ArticleDateModified' on entity type 'Article' cannot be marked as nullable/optional because the type of the property is 'DateTime' which is not a nullable type. Any property can be marked as non-nullable/required, but only properties of nullable types and which are not part of primary key can be marked as nullable/optional.
so, I wonder what is the use of IsRequired(false) here if all I have to do to make a database column nullable is to make it nullable in my domain class?
Based on the note in this documentation page, it would appear that support for doing this declaratively was rescinded. To wit:
A property whose CLR type cannot contain null cannot be configured as optional. The property will always be considered required by Entity Framework.
That this was intentional can be seen in the design discussions from the project hosting on GitHub, specifically:
That is, a property marked as nullable supports null values, while a property marked as non-nullable must never contain null values. It follows from this that marking a property which is of a non-nullable CLR type as allowing nulls will not be allowed. This is different from the EF6 behavior where this is allowed. [emphasis added]
The upshot is, in EF7 a NULL column strictly implies a nullable mapped property. If your property is nullable, the associated column must be NULL unless you mark or configure it with IsRequired.
Response to OP edits
That's interesting, I didn't initially see the documentation on an IsRequired(bool) API. I found a discussion point on it in some June meeting notes that state that this would be the equivalent of EF6's IsOptional():
.IsOptional() - We'll provide this functionality via calling Required(false)
.IsRequired() - Provide Required() with the same functionality
Even though this was the original intent, the design decision to rescind support dates from October. (Per update) attempting to set IsRequired(false) on a non-nullable property results in a run-time error, rather than having been removed entirely.
Though now superfluous, the API cannot be removed without breaking valid code: it wasn't implemented with separate IsRequired(bool) and IsRequired() definitions, but with a single IsRequired(bool required = true). If it were removed and replaced with the parameterless version it would be a breaking change.
Em... Declare Property as nullable?
class Article
{
public DateTime? ArticleDateModified {get;set;}
}
There is not IsOptional in EntityFrameworkCore but there is IsRequired to do the oposite. By default field are nullable if the C# type is nullable.
And more over you cannot set the foreign key which is the primary key of another table using the IsRequire(false) method. if you do so EntityframeworkCore throw an error.
public class User
{
public int Id {get; set;}
public string Username {get;set}
public byte Interest {get;set;}
public Interest Interest {get;set;}
}
public class Interest
{
public byte Id {get;set;}
public string Name {get;set;}
}
ApplicationDbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.property(u => u.InterestId)
.isRequired(false);
}
Error
The property 'InterestId' on entity type 'User' cannot be marked as nullable/optional because the type of the property is 'byte' which is not a nullable type. Any property can be marked as non-nullable/required, but only properties of nullable types and which are not part of primary key can be marked as nullable/optional.
So the best way is to make the property nullable like this.
public byte? InterestId {get; set;}
public Interest Interest {get; set;}

How to add Foreign Key Properties subsequently to a Code First Model?

Given the Model:
Public Class Customer
Property Id() As Guid
Property FirstName() As String
Property MiddleName() As String
Property LastName() As String
Property Addresses() As ICollection(Of Address)
End Class
Public Class Address
Property Id() As Guid
Property Name() As String
Property Street() As String
Property City() As String
Property Zip() As String
Public Property Customer() As Customer
End Class
Entity Framework 6 Code First has created a column called Customer_Id in my table Addresses. Now, I'd like to add a Property Customer_Id to my class Address that represents the existing foreign key relation:
Public Class Address
Property Id() As Guid
Property Name() As String
Property Street() As String
Property City() As String
Property Zip() As String
Public Property Customer() As Customer
//Added
Public Property Customer_Id() As Guid
End Class
Unfortunately this results in an InvalidOperationException while creating the DbContext saying:
The model backing the 'DataContext' context has changed since the database was created.
I tried different property names (with and without underscore, different casing). But still no luck. So, what is the correct way to add those properties subsequently without the need for migrations? I assume it's possible, because the model does not really change, I am only changing from an implicit declaration of a property to an explicit...
Update:
The responses show me, that I did not explain the problem very well. After some more reading I found the correct names now: I have an application which is installed several times at customer locations (therefore dropping and recreating the database is no option). Currently, it depends on Entity Framework's Independent Associations, but I want to have the Foreign Key in my entity as well (this is no change to the model, the foreign key is already there, but does not exist as a property in my entity, since this is currently only relying on the IA instead). I did not manage to add it without EF thinking my Database is outdated.
for me two ways :
drop table __MigrationHistory : that is have the new model runs, but forget migration functionalities
create a new db by changing the connection string of the application. Replace old __MigrationHistory by __MigrationHistory of the newly created db
Never tested the second solution, but it should work.
Before using any solution:
backup you db.
Before using first solution: are you sure you will never need migration functionalities ?
This exception is because you change your model. You have to set migration strategy. Please look at:
http://msdn.microsoft.com/en-us/data/jj591621#enabling
(edited)
First of all you have to remove that exception. Even if you didn't add any new column to your database your model has changed because you added new property to Address class. If you check your DB you will find dbo.__MigrationHistory table with Model column. Last (earliest) value from that column is used for checking that your model and DB are compatible. I'm not sure but I think that EF stores there binary serialized model. So the solution is - recreate DB or add migration (probably empty migration).
(edited)
When you want to set FK you can do this very simple by Data Annotations
// c# example
public class Address
{
...
public string CustomerId { get; set; }
[ForeignKey("CustomerId")]
public Customer Customer { get; set; }
}
or in fluent api
// c# example
modelBuilder.Entity<Address>()
.HasRequired(arg => arg.Customer)
.WithMany()
.HasForeignKey(arg => arg.CustomerId);
or look at:
http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations.aspx
http://msdn.microsoft.com/en-us/data/hh134698.aspx

Selectively updating (and not updating) fields

Is there a way to tell EF 4.3+ not to update some fields?
We have a standard in the DB where each table has a 'CreatedBy' column. I would like to make sure that it is impossible to update that column.
The safest I see it would be to tell EF not to map the corresponding properties but just for the update.
Is there a way to do that?
If you are using code first you can use the DatabaseGenerated attribute to configure the property as Computed.
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string Foo { get; set; }

How to deal with "computed" property in Entity Framework 4.1?

I have a model as below:
public class Post
{
public int Id {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
public virtual ICollection<Reader> Readers {get;set;}
public int Value {get;set;}
}
The rule is Value = Comments.Count * 2 + Readers.Count.
What is the right and convenient way to deal with the "computed" property of "Value"?
I think it is the best that the "Value" can be calculated and saved automatically when Comments or Readers add/remove element.
but the "DatabaseGeneratedAttribute" seems no use here.
Thank you!
This is not supported. There is no way to make Value available for linq-to-entities queries if it is not mapped to database column. In case of EF using EDMX for mapping this can be sometimes solved by using custom mapped SQL function or model defined function but code first mapping doesn't support anything of that. Other way is to create database view and map your entity to view but in such case entity will be read only.
Once you use .NET code for defining value it is always only client side property computed from data loaded from database. If you don't want to recompute property every time you need observable collections with event handler changing precomputed value each time the collection changes.
DatabaseGenerated attribute just marks your property as generated by database - in such case you cannot change its value and database must ensure that correct value will be stored in your table.
I think your column value is based on two mapped properties. Use NotMappedAttribute to Exclude a Property from the Database Schema and Load values in runtime.
public class Post
{
public int Id {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
public virtual ICollection<Reader> Readers {get;set;}
[NotMapped]
public int Value
{
get return Comments.Count * 2 + Readers.Count;
}
}
You may use the DatabaseGenerated attribute and then create triggers in the db for calculating the Value. You can create the triggers in the migrations, or db seed method.