NHibernate write value = NULL when ID < 0 - c#

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.

Related

'Nullable object must have a value.' for List in LINQ c#

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).

NHibernate, refresh modifed object throws AssertionFailure {null identifier}

I use NHibernate 4,
I would like to implement a function which permit to refresh an modified object.
My object contains an ID and an association one-to-many with objects with ID2 ad a string
In my association, i insert a new object association, so ID2 is null because it generate by hilow generator when save the main object in database.
so when i cause refresh for to reload the original object, I have an assertion failure (null identifier) when there is an new object with ID = null (it's normally ok, no problem when i saveOrUpdate.
I put notFound = ignore in my mapping but with no effect when execute.
Please give me a way for resolve my problem
Thank you in advance.
In my association, i insert a new object association, so ID2 is null because it generate by hilow generator when save the main object in database.
There is a somewhat inexact statement here. The hilo generator strategy generates the id before the object is inserted in database. It does it on Save, without Save actually inserting the entity into database until the session is flushed.
If your id stays null, this is very likely because you have not yet persisted the entity in the session. Call Save on it, and your id will no more be null, while the entity will not be yet in database unless you have flushed the session (or changed the generator strategy for one requiring immediate insert, as identity).
Now refreshing an object not already in database looks anyway as an error to me. What do you expect from such an operation?
not-found="ignore" is not meant for handling refreshing of non existent entities. It is there for allowing ignoring an invalid foreign key in database.

Null object pattern with entity framework code first

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).

Entity Framework children collection

I have a table named "Notaries":
NotaryID int,
NotaryName nvarchar(MAX)
and table named "NotaryPhones":
PhoneID int,
NotaryID int,
PhoneNumber nvarchar(50)
So, relationship "one-to-many". Now I want to clear all phones, depending on the notary. My code:
Notary.Models.Notary notary = (from i in db.Notaries where i.NotaryID == model.NotaryID.Value select i).FirstOrDefault();
notary.CityID = Convert.ToInt32(model.City.SelectedItem);
notary.NotaryPhones.Clear();
db.SaveChanges();
but I get an error:
The operation failed: The relationship could not be changed because
one or more of the foreign-key properties is non-nullable. When a
change is made to a relationship, the related foreign-key property is
set to a null value. If the foreign-key does not support null values,
a new relationship must be defined, the foreign-key property must be
assigned another non-null value, or the unrelated object must be
deleted.
If I remove the string
notary.NotaryPhones.Clear();
it works. I understand, that this is a trivial thing, but don't understand how to fix it
What's going on is that your notary.NotaryPhones.Clear(); is removing the foreign-key reference from your NotaryPhone table to your Notary table. Because this is set up as a non-nullable key so that you don't have orphan phone records, you're receiving that error.
What you'll want to do instead is set up a method in your repository that will call context.NotaryPhones.Remove(**instance variable pointing to one of the phones to delete**); and that will delete them from the database.
CLARIFICATION
The reason why it removes the foreign key reference is that notary.NotaryPhones.Clear() just removes those objects from the notary object. The objects will continue to exist the way that you have written this.
So when the .Clear() is executed, it takes your phone.NotaryID property and gets rid of the ID pointer to the notary. Since you're not assigning it anything else, the value it tries to assign is null (the only value that couldn't possibly point to a Notary object). But, because you have it set up as an int, and not an int?, it can't make that assignment and it throws the error you see.
You said you're trying to delete the objects, so you need to remove them from the database. To do that, you do what I explained above.
please excuse the example if there are syntax errors, I am currently working in VB but the approach is the same
foreach (NotaryPhones np in notary.NotaryPhones)
{
db.NotaryPhones.DeleteObject(np);
}
then save your changes with
db.SaveChanges();
Clear just removes entity from the related collection. it doesn't remove entity from database. you have to delete each NotaryPhone from corresponding DbSet.

Assigning Entity Keys in Entity Framework

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.

Categories