- edited description
InsertOrReplaceAllWithChildren crashes when child list object is empty instead null
I am having an web api which returns list of objects with sub objects. for example
- List<ObjectMain>-> List<ObjectImage> ObjectImages
->List<ObjectComment> ObjectComments
In my api I am returning Objects with sub objects included. By default if Object doesnt have ObjectImages, regardless list is empty or null, it will throw exception
public IQueryable<Object> GetObjectsWithChildren()
{
return db.Objects
.Include(e => e.ObjectImages)
.Include(e => e.ObjectComments);
}
So in my viewmodel I make a call to api to get Objects with children as below. Objects are returned but some objects dont have objectImage mapping
var Items = await Api.GetObjectsWithChildren();
if (Items?.Count > 0)
{
await db_async.InsertOrReplaceAllWithChildrenAsync(Items);
}
Problem is I have a property which is defined as NotNull(ImageId) in this object, since Object is returned as empty list or null, it will complain about this object with the exception below. Why is attempting to insert if object is null or empty
public class ObjectImage
{
[PrimaryKey, AutoIncrement, Unique, NotNull]
public int id { get; set; }
[ForeignKey(typeof(Database.Model.Image)), NotNull]
public int ImageId { get; set; }
SQLite.Net.NotNullConstraintViolationExceptionNOT NULL constraint failed: ObjectImage.ImageId
Raw
at SQLite.Net.SQLiteCommand.ExecuteNonQuery () [0x000c7] in <00cd4299895343388a532f755967caf0>:0
at SQLite.Net.SQLiteConnection.Execute (System.String query, System.Object[] args) [0x00044] in <00cd4299895343388a532f755967caf0>:0
at SQLiteNetExtensions.Extensions.WriteOperations.UpdateOneToManyInverseForeignKey (SQLite.Net.SQLiteConnection conn, System.Object element, System.Reflection.PropertyInfo relationshipProperty) [0x00200] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensions/Extensions/WriteOperations.cs:461
at SQLiteNetExtensions.Extensions.WriteOperations.UpdateInverseForeignKeys (SQLite.Net.SQLiteConnection conn, System.Object element) [0x00040] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensions/Extensions/WriteOperations.cs:394
at SQLiteNetExtensions.Extensions.WriteOperations.UpdateWithChildren (SQLite.Net.SQLiteConnection conn, System.Object element) [0x0000e] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensions/Extensions/WriteOperations.cs:51
at SQLiteNetExtensions.Extensions.WriteOperations.InsertAllWithChildrenRecursive (SQLite.Net.SQLiteConnection conn, System.Collections.IEnumerable elements, System.Boolean replace, System.Boolean recursive, System.Collections.Generic.ISet`1[T] objectCache) [0x0007f] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensions/Extensions/WriteOperations.cs:177
at SQLiteNetExtensions.Extensions.WriteOperations.InsertOrReplaceAllWithChildren (SQLite.Net.SQLiteConnection conn, System.Collections.IEnumerable elements, System.Boolean recursive) [0x00000] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensions/Extensions/WriteOperations.cs:115
at SQLiteNetExtensionsAsync.Extensions.WriteOperations+<InsertOrReplaceAllWithChildrenAsync>c__async4+<InsertOrReplaceAllWithChildrenAsync>c__AnonStoreyC.<>m__0 () [0x00013] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensionsAsync-PCL/Extensions/WriteOperations.cs:143
at System.Threading.Tasks.Task.InnerInvoke () [0x00012] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2879
at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:447
at SQLiteNetExtensionsAsync.Extensions.WriteOperations+<InsertOrReplaceAllWithChildrenAsync>c__async4.MoveNext () [0x0005f] in /Users/redent/Documents/workspace/sqlite-net-extensions/SQLiteNetExtensionsAsync-PCL/Extensions/WriteOperations.cs:138
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:113
Comments (4)
-
reporter -
The error looks self-explanatory. You have a not nullable foreign key property that it's being set to
null
because the object it references is alsonull
. If this case should be supported, remove theNotNull
property from theForeignKey
property. Otherwise check why your relationship property (not included in your sample code) isnull
when the object is being inserted. -
reporter You say in your other post. it is not good practice to use InsertOrReplaceAllWithChildren when there are OneToMany or ManyToOne relationships. Is it better to use InsertAllWithChildren instead? if yes, does it handle updates as well if there are existing rows and childen?
-
Calling
InsertOrReplaceWithChildren
will callInsertOrReplace
instead ofInsert
when inserting objects to database. It doesn't add any additional handling. It's hard to tell which one is better for you, because they do different things. - Log in to comment