We've implemented the null object pattern in our domain model. We're using code first with fluent api to persist our domain model.
One of our entities has a navigation property - this navigation property is a FK and is where we use the null object pattern.
Our null object has the default 0 value for it's id.
Is there a way with fluent api (or direct mappings) to tell EF 'if this is one of those null objects, REALLY throw null in the database fk field, and not that invalid 0 id'.
EDIT:
As an example, imagine you have a Student Entity, and a FavoriteSubject entity. A student has a reference to a FavoriteSubject, unless he has no FavoriteSubject, then the null object would be something like NoFavorite.
When we persist this to the database, we get the Id of NoFavorite (0) where we'd really like NULL in the db as NoFavorite is a null object (follows null object pattern).
Related
In database I have next model tblWorkItem with next field:
public List<xWorkItemItemFailReason> WorkItemItemFailReasons { get; set; }
When I am trying to get tblWorkItem data from database
_db.tblWorkItem.Where(x=>x.WorkItemItemFailReasons != null)
I have next error
System.InvalidOperationException: 'Nullable object must have a value.'
How I can check if this field is not null?
Problem in xWorkItemItemFailReason class. It has some property of primitive type (int, long, ...) that is not nullable, but has no value in database table.
Check them.
In your modal class have some not nullable field so when fetching from database it comes with null values. so make it nullable .public int? FieldName {Get;set;}
if its .net core 3.0 or earlier there is a known issue where
Simple query filter breaks simple projection
https://github.com/dotnet/efcore/issues/13517
You should also make sure there are no data integrity problems with your foreign key relationships. A foreign key value in the parent table that doesn't exist in the child table will throw this exception too (e.g., you set the foreign key to 0 instead of null if there's no child, and no child record in the database has a key value of 0).
Is there a way in C# to check if a navigational property exists without getting an The ObjectContext instance has been disposed and can no longer be used for operations... exception ?
For example, if entity framework is used to load an Animal object which has a Habitat navigational property and you do animal.Habitat != null this will throw a The ObjectContext instance... exception.
Any ideas?
You must include this object into the query result so that you can still access after data context is disposed of.
ctx.animal.Include(m => m.Habitat).FirstOrDefault();
I am trying to update a foreign key using Entity Framework 7. But it is giving error: The property 'Y' could not be found in object 'X'. I have tried many different solution but still not working. The sample code:
class X
{
property Y {get; set;} -> property Y is a foreign key and also a complex type
}
In table 'X' we have a column 'Y_ID' which is the foreign key.
Note: I just want to update the foreign key. E.g. Initially class 'X' is pointing to 'NULL', I want to update class 'X' to point to 'Y1'
The Entity Framework 7 code:
var x = this.GetX();
this.mainContext.Xs.Attach(x);
var xEntry = this.mainContext.Entry(x);
xEntry.Property("Y").CurrentValue = "Y1"; // Error at this line
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);
Detailed Error:
The property 'Y' on entity type 'X' could not be found. Ensure that the property exists and has been included in the model.
Edit
The approach Fabien suggested in his comment works fine. But the problem is we only know about which property to update is at runtime. If I use reflection to achieve this, the problem is entity framework treats the object as new and tries to create it (INSERT) and then throws Primary Key violation (No duplicate entries allowed)
So, is there a way where I can't still update an object property which acts like a foreign key in EF? (I don't know exact property at compile time).
If you get the entities "X" and "Y" from your context, then they're automatically tracked by the ChangeTracker. So if you assign "Y" property of the "X" object with an "Y" instance retrieved from your context and call SaveChanges or SaveChangesAsync, EntityFramework will automically do the stuff for you.
var x = this.GetX();
x.Y = "Y1";
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);
By convention, your property "Y" on object "X" should be virtual to indicate that it's an foreign key.
Edit 1 :
If I understand correctly, you want to update properties of your object dynamically at runtime, with values that comme from a web api.
1st way :
Like you did, you can attach your "X" object to your context instance to begin tracking of the entity with EntityState.Unchanged, and then flag each property that need to be updated :
this.mainContext.Xs.Attach(x);
var entry = this.mainContext.entry(x);
entry.Property(p => p.Y).CurrentValue = "Y1";
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);
When attaching an entity, you can specify the GraphBehavior, it tell EntityFramework if navigation properties should traversed or not.
2nd way :
Using the DbSet.Update() method :
this.mainContext.Xs.Update(x);
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);
It's automatically begin tracking of the entity with the state EntityState.Modified, all properties will be marked as modified. You should watch out when using this method, because all properties will be updated, if some of them are not inititialized in your "X" object, you could lost some data. To prevent that case, you should always validate inputs.
If you want to keep your domain models de-coupled form any ORM, then you should think to separate entity types and domain types. You can use an object mapper like Automapper to map entity to domain type and vice versa. In that way you clearly separate what you do at data access layer and business logic layer.
I have a very precise gap of knowledge of the assignement of the entity keys in entity framework.
When you set a variable to become the entity key of an entity, if you are doing code first or model first it sets the column as identity but what if I assign the entity key to 0 in the default constructor of my model first class, what does EF do?
Will EF notice that it was an auto assignement and ignore the default value I set in the constructor?
Or should I never assign an entity key other than when im retrieving data?
So far I have yet to see the first scenario where there is absolutely no alternative for setting an EntityKey object. But I assume you're not referring to that but to setting a key value.
Setting a primary key value is hardly ever necessary when the key is generated by the database (identity column). If you want EF to insert an entity you don't set the primary key, but you set its EntityState to Added (either directly or indirectly).
I can think of one scenario where setting primary key values is useful: using stub entities. For example, suppose you know that object A with id value 3 must be deleted, but object A has not been fetched from the database. So there is no object which state can be changed to Deleted. In that case you can prevent a roundtrip to the database by creating a stub entity A that only has its Id value filled, attach it to a context as Deleted and save changes.
We would like to implement a simple rule in which NHibernate would assign (persist) NULL to the database when the ID for the entity is equal to -1. For example, we have an "in system" account which should be persisted to the database as NULL.
If we try to persist the ID of -1 to the database we get a Foreign key exception because the ID does not exist in the foreign table.
We are using NHibernate with FluentNhibernate.
I think you didn't a proper mapping of your entity. If it were correct, you should made any trick: you should not see an ID, but a reference to another entity, and in this case you will persist the reference with a null value. Even in the wrong case you want map the entity with a reference expressed as an ID ( that is almost always wrong ) if this id is nullable, map it as a nullable so you have int? and you can fit null to mean null, instead of the -1 trick.
See Comments
If a custom entity is internally used as a null value, a session interceptor could help: working on the OnSave and treat the special case by replacing the dummy entity with null.
Here you can find the documentation about NH interceptors.
At the 11.2 chaper od the same doc there is the portion related to events, equivalents for this kind of problem.