	<rss version="2.0">
		<channel>
			<title>LLBLGen Pro Support System LLBLGen Pro Runtime Framework feed</title>
			<link>https://www.llblgen.com/tinyforum//Forum/7</link>
			<description>This is the RSS feed for the forum LLBLGen Pro Runtime Framework on the LLBLGen Pro Support System forum system.</description>
			<ttl>30</ttl>
			<language>en-us</language>
				<item>
					<title>Insert ordering regression after upgrade from LLBLGen 5.1.0 to 5.11.1 by Otis</title>
					<description>&lt;p&gt;First, please next time don&#x27;t generate a wall of text with some AI tool, write it out manually. thanks.&lt;/p&gt;&#xA;&lt;p&gt;In 5.5.2 we made a bugfix, which is described by this post: &lt;a href=&quot;https://www.llblgen.com/tinyforum/Message/Goto/144684&quot; rel=&quot;nofollow&quot;&gt;https://www.llblgen.com/tinyforum/Message/Goto/144684&lt;/a&gt; &lt;/p&gt;&#xA;&lt;p&gt;Before that fix, it was undefined what the order was, basically the order in which the entities were stored in the unit of work. We don&#x27;t utilize relationships for figuring out the order. To make the runtime figure out what the order is, it&#x27;s best to define the relationships through the navigators, as the topological sort algorithm of the graph will then find them. This indeed requires to specify true for recursing the graph. This is very fast and doesn&#x27;t mean all entities in the graph are added for the save operation; only the ones which have been changed or are new are added (as you wanted to save them anyway!). &lt;/p&gt;&#xA;</description>
					<author>Otis</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29094#154700</link>
					<pubdate>Thu, 21 May 2026 06:23:08 GMT</pubdate>
					<category>Insert ordering regression after upgrade from LLBLGen 5.1.0 to 5.11.1</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29094#154700</guid>
				</item>
				<item>
					<title>Insert ordering regression after upgrade from LLBLGen 5.1.0 to 5.11.1 by Ashutosh</title>
					<description>&lt;p&gt;Hello LLBLGen Support Team,&lt;/p&gt;&#xA;&lt;p&gt;We are currently upgrading our application from LLBLGen Pro 5.1.0 to 5.11.1 and are encountering a change in UnitOfWork insert ordering behavior which appears to affect parent-child entity persistence.&#xD;&#xA;We would appreciate clarification on whether our understanding is correct and whether our proposed fix aligns with the intended 5.11 behavior.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Problem Summary:&lt;/strong&gt;&#xD;&#xA;After upgrading from 5.1.0 to 5.11.1, inserts that previously succeeded now fail with FK violations because child entities are inserted before parent entities.&lt;/p&gt;&#xA;&lt;p&gt;Example:&#xD;&#xA;WorkflowDraftStatus references WorkflowDraftSchema&#xD;&#xA;Both are new entities in the same UnitOfWork&#xD;&#xA;In 5.1.0 the parent was inserted first automatically&#xD;&#xA;In 5.11.1 the child may be inserted first unless navigation properties are explicitly wired&lt;/p&gt;&#xA;&lt;p&gt;Our current understanding is that this is due to a change in how insert dependency ordering is determined.&lt;/p&gt;&#xA;&lt;p&gt;Observed Behavioral Difference:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;In 5.1.x&lt;/strong&gt;:&#xD;&#xA;Insert ordering appeared to be driven primarily by static FK metadata / entity type relationships&#xD;&#xA;Even when only scalar FK fields were assigned, inserts were ordered correctly&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;In 5.11.x:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Insert ordering appears to rely on instance-level relationship graphs&#xD;&#xA;Dependency edges are discovered through related entity navigation wiring&#xD;&#xA;Scalar FK assignment alone no longer seems sufficient&lt;/p&gt;&#xA;&lt;p&gt;Specifically, we observed that ordering now depends on:&lt;/p&gt;&#xA;&lt;p&gt;IEntityCore.GetDependentRelatedEntityCoreInstances() &#xD;&#xA;_relatedEntitiesToCommit being populated&#xD;&#xA;Navigation setters such as SetSingleRelatedEntityNavigator / SetRelatedEntity being invoked&lt;/p&gt;&#xA;&lt;p&gt;In our BusinessObject layer, many relationships historically only set scalar FK values and do not always invoke generated navigation setters.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Question 1&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Is it correct that:&#xD;&#xA;5.1.x used a more metadata/FK-driven insert pre-sort&#xD;&#xA;5.11.x now depends primarily on per-instance navigation dependency graphs?&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Question 2&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;We found that explicitly wiring navigation properties via reflection on the IEntity2 instance resolves ordering issues in many cases:&lt;/p&gt;&#xA;&lt;p&gt;PropertyInfo.SetValue(childEntity, parentEntity);&lt;/p&gt;&#xA;&lt;p&gt;Our understanding is that this still correctly invokes the generated entity setter and therefore:&lt;/p&gt;&#xA;&lt;p&gt;populates _relatedEntitiesToCommit&#xD;&#xA;invokes SetSingleRelatedEntityNavigator&#xD;&#xA;participates in dependency graph construction&lt;/p&gt;&#xA;&lt;p&gt;Can you confirm this is a supported and valid approach?&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Question 3&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;We also tested changing:&lt;/p&gt;&#xA;&lt;p&gt;uow.AddForSave(entity);&lt;/p&gt;&#xA;&lt;p&gt;to:&lt;/p&gt;&#xA;&lt;p&gt;uow.AddForSave(entity, null, true, true);&lt;/p&gt;&#xA;&lt;p&gt;Specifically enabling:&lt;/p&gt;&#xA;&lt;p&gt;recurseSavedAndDeletedEntities = true&lt;/p&gt;&#xA;&lt;p&gt;This appears to resolve ordering issues consistently.&lt;/p&gt;&#xA;&lt;p&gt;Our understanding is that recursion:&lt;/p&gt;&#xA;&lt;p&gt;walks GetAllRelatedEntities()&#xD;&#xA;registers additional dependency edges inside the UnitOfWork&#xD;&#xA;enables proper topological ordering even if scalar FK assignment bypassed relationship tracking earlier&lt;/p&gt;&#xA;&lt;p&gt;Is this the intended mechanism in 5.11.x for ensuring graph dependency ordering?&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Question 4&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Would you recommend:&lt;/p&gt;&#xA;&lt;p&gt;explicitly wiring navigation properties everywhere, OR&#xD;&#xA;enabling recurseSavedAndDeletedEntities=true for save operations involving complex object graphs?&lt;/p&gt;&#xA;&lt;p&gt;We are hesitant to globally enable recursion because it expands save scope and may introduce unintended persistence behavior.&lt;/p&gt;&#xA;&lt;p&gt;Current Thinking&lt;/p&gt;&#xA;&lt;p&gt;Our current preferred approach is:&lt;/p&gt;&#xA;&lt;p&gt;Keep explicit relationship wiring in the package installation path&#xD;&#xA;Use:&#xD;&#xA;uow.AddForSave(entity, null, true, true)&#xD;&#xA;only in the package install pipeline&#xD;&#xA;Avoid globally changing all BusinessContext save operations&lt;/p&gt;&#xA;&lt;p&gt;Does this align with recommended LLBLGen usage patterns for 5.11.x?&lt;/p&gt;&#xA;&lt;p&gt;Any clarification on the intended dependency-ordering behavior changes between 5.1 and 5.11 would be greatly appreciated.&lt;/p&gt;&#xA;&lt;p&gt;Thank you.&lt;/p&gt;&#xA;</description>
					<author>Ashutosh</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29094#154699</link>
					<pubdate>Wed, 20 May 2026 18:04:22 GMT</pubdate>
					<category>Insert ordering regression after upgrade from LLBLGen 5.1.0 to 5.11.1</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29094#154699</guid>
				</item>
				<item>
					<title>Custom type converter and nullability in projection by Findev</title>
					<description>&lt;blockquote&gt;&lt;p class=&quot;quote-nickname&quot;&gt;Otis wrote:&lt;/p&gt;&#xA;&lt;p&gt;That was a bit of complicated debugging as the problem wasn&#x27;t showing till the lambda was executed which is impossible to step through, but checking what the runtime is building for the projection lambda revealed what the core of the issues is. The DTO  projection will use a helper method for the &lt;code&gt;ToValue&amp;lt;datetime?&amp;gt;&lt;/code&gt;, namely &lt;code&gt;DataReaderProjectionRow.GetNullableDateTime(int i)&lt;/code&gt;, which checks if the value obtained from the datareader is DBNull.Value and if so, return null. As your typeconverter converts DBNull.Value to null, this check fails and it returns a normal DateTime. &lt;/p&gt;&#xA;&lt;p&gt;So to fix this, change line 24 of your type converter to &lt;code&gt;return value&lt;/code&gt; and it works fine. &lt;/p&gt;&#xA;&lt;p&gt;Like: &lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;if (value == null || value == DBNull.Value)&#xA;{&#xA;    return value;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;ah, the case of not all nulls are created equally and neither they are treated as such &lt;img src=&quot;/tinyforum/pics/emojis/simple_smile.png&quot; class=&quot;emoji&quot; alt=&quot;simple_smile&quot;/&gt;&lt;/p&gt;&#xA;&lt;p&gt;Thank you!&lt;/p&gt;&#xA;</description>
					<author>Findev</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29076#154612</link>
					<pubdate>Sun, 08 Mar 2026 10:35:22 GMT</pubdate>
					<category>Custom type converter and nullability in projection</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29076#154612</guid>
				</item>
				<item>
					<title>Custom type converter and nullability in projection by Otis</title>
					<description>&lt;p&gt;That was a bit of complicated debugging as the problem wasn&#x27;t showing till the lambda was executed which is impossible to step through, but checking what the runtime is building for the projection lambda revealed what the core of the issues is. The DTO  projection will use a helper method for the &lt;code&gt;ToValue&amp;lt;datetime?&amp;gt;&lt;/code&gt;, namely &lt;code&gt;DataReaderProjectionRow.GetNullableDateTime(int i)&lt;/code&gt;, which checks if the value obtained from the datareader is DBNull.Value and if so, return null. As your typeconverter converts DBNull.Value to null, this check fails and it returns a normal DateTime. &lt;/p&gt;&#xA;&lt;p&gt;So to fix this, change line 24 of your type converter to &lt;code&gt;return value&lt;/code&gt; and it works fine. &lt;/p&gt;&#xA;&lt;p&gt;Like: &lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;if (value == null || value == DBNull.Value)&#xA;{&#xA;    return value;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;</description>
					<author>Otis</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29076#154611</link>
					<pubdate>Sun, 08 Mar 2026 09:28:58 GMT</pubdate>
					<category>Custom type converter and nullability in projection</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29076#154611</guid>
				</item>
				<item>
					<title>Custom type converter and nullability in projection by Otis</title>
					<description>&lt;p&gt;Thanks, we&#x27;ll look into it!&lt;/p&gt;&#xA;</description>
					<author>Otis</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29076#154610</link>
					<pubdate>Sun, 08 Mar 2026 08:31:55 GMT</pubdate>
					<category>Custom type converter and nullability in projection</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29076#154610</guid>
				</item>
				<item>
					<title>Custom type converter and nullability in projection by Findev</title>
					<description>&lt;blockquote&gt;&lt;p class=&quot;quote-nickname&quot;&gt;Otis wrote:&lt;/p&gt;&#xA;&lt;p&gt;The type converters are run right after the row has been received from the datareader (See &lt;code&gt;FetchProjectionFromReader&lt;/code&gt; in ProjectionUtils.cs ). The value is therefore DBNull.Value in the row from the datareader. At least, it should be. &lt;/p&gt;&#xA;&lt;p&gt;Please place a breakpoint on the &lt;code&gt;if (value == null || value == DBNull.Value)&lt;/code&gt; line during the projection and see if that&#x27;s indeed the case. Also, without more information, e.g. the C# query and the SQL query executed, it&#x27;s hard to say what&#x27;s wrong... &lt;/p&gt;&#xA;&lt;p&gt;(e.g. are the converters run at all? )&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;was hoping would be able to dodge the repro &lt;img src=&quot;/tinyforum/pics/emojis/simple_smile.png&quot; class=&quot;emoji&quot; alt=&quot;simple_smile&quot;/&gt; &#xD;&#xA;here you go: https://drive.google.com/file/d/1H-5EtgA8z35qm1zlVWfv4GgxwkYLMiTI/view?usp=sharing&lt;/p&gt;&#xA;</description>
					<author>Findev</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29076#154609</link>
					<pubdate>Sat, 07 Mar 2026 10:51:28 GMT</pubdate>
					<category>Custom type converter and nullability in projection</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29076#154609</guid>
				</item>
				<item>
					<title>Custom type converter and nullability in projection by Otis</title>
					<description>&lt;p&gt;The type converters are run right after the row has been received from the datareader (See &lt;code&gt;FetchProjectionFromReader&lt;/code&gt; in ProjectionUtils.cs ). The value is therefore DBNull.Value in the row from the datareader. At least, it should be. &lt;/p&gt;&#xA;&lt;p&gt;Please place a breakpoint on the &lt;code&gt;if (value == null || value == DBNull.Value)&lt;/code&gt; line during the projection and see if that&#x27;s indeed the case. Also, without more information, e.g. the C# query and the SQL query executed, it&#x27;s hard to say what&#x27;s wrong... &lt;/p&gt;&#xA;&lt;p&gt;(e.g. are the converters run at all? )&lt;/p&gt;&#xA;</description>
					<author>Otis</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29076#154608</link>
					<pubdate>Sat, 07 Mar 2026 07:06:08 GMT</pubdate>
					<category>Custom type converter and nullability in projection</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29076#154608</guid>
				</item>
				<item>
					<title>Missing ModelInfoProviderSingleton by Otis</title>
					<description>&lt;p&gt;&lt;a href=&quot;https://www.llblgen.com/tinyforum/Thread/7722/1&quot; rel=&quot;nofollow&quot;&gt;https://www.llblgen.com/tinyforum/Thread/7722/1&lt;/a&gt;&lt;/p&gt;&#xA;</description>
					<author>Otis</author>
					<link>https://www.llblgen.com/tinyforum/Thread/28692#154607</link>
					<pubdate>Sat, 07 Mar 2026 06:53:57 GMT</pubdate>
					<category>Missing ModelInfoProviderSingleton</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/28692#154607</guid>
				</item>
				<item>
					<title>Custom type converter and nullability in projection by Findev</title>
					<description>&lt;p&gt;Hi,&lt;/p&gt;&#xA;&lt;p&gt;MSSQL,  ORM 5.12.x. Table has a nullable column of type datetime2(0). I have a very old custom converter which basically validates that all DateTimes are UTC in both directions. Here is the slightly modernized version:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;using System;&#xA;using System.Collections;&#xA;using System.ComponentModel;&#xA;using System.Globalization;&#xA;&#xA;namespace SD.LLBLGen.Pro.TypeConverters;&#xA;&#xA;public class SqlDateTimeToUtcDateTimeConverter : TypeConverter&#xA;{&#xA;    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)&#xA;    {&#xA;        return IsDateTime(sourceType);&#xA;    }&#xA;&#xA;    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)&#xA;    {&#xA;        return IsDateTime(destinationType);&#xA;    }&#xA;&#xA;    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)&#xA;    {&#xA;        if (value == null || value == DBNull.Value)&#xA;        {&#xA;            return null;&#xA;        }&#xA;&#xA;        if (value is not DateTime dt)&#xA;        {&#xA;            throw new NotSupportedException(&#xA;                $&amp;quot;Conversion from a value of type &#x27;{value.GetType()}&#x27; to System.DateTime isn&#x27;t supported&amp;quot;&#xA;            );&#xA;        }&#xA;&#xA;        return DateTime.SpecifyKind(dt, DateTimeKind.Utc);&#xA;    }&#xA;&#xA;    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)&#xA;    {&#xA;        if (destinationType == null)&#xA;        {&#xA;            throw new ArgumentNullException(nameof(destinationType));&#xA;        }&#xA;&#xA;        if (!IsDateTime(destinationType))&#xA;        {&#xA;            throw new NotSupportedException($&amp;quot;Conversion to type &#x27;{destinationType}&#x27; isn&#x27;t supported&amp;quot;);&#xA;        }&#xA;&#xA;        if (value == null)&#xA;        {&#xA;            return null;&#xA;        }&#xA;&#xA;        if (value is not DateTime dt)&#xA;        {&#xA;            throw new ArgumentException(&amp;quot;Value isn&#x27;t of type DateTime&amp;quot;, nameof(value));&#xA;        }&#xA;&#xA;        if (dt.Kind != DateTimeKind.Utc)&#xA;        {&#xA;            throw new ArgumentException(&amp;quot;Value must be DateTime UTC&amp;quot;, nameof(value));&#xA;        }&#xA;&#xA;        return dt;&#xA;    }&#xA;&#xA;    public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)&#xA;    {&#xA;        return DateTime.UtcNow;&#xA;    }&#xA;&#xA;    private static bool IsDateTime(Type type) =&amp;gt; type == typeof(DateTime);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;while I didn&#x27;t dig deeper and in isolation, but rather via existing test it seems that nullablity is not being respected in projection when field has converter assigned. I.e. if I fetch entities directly and that column is null in the database - corresponding entity property is null as well, however, when I fetch via projection:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;DateLastValidated = XXXFields.DateLastValidated.ToValue&amp;lt;DateTime?&amp;gt;()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;then instead of a null it seems to get a &lt;code&gt;DateTime.MinValue&lt;/code&gt;. If in Designer for that field &amp;quot;TypeConverter to use&amp;quot; is set to &amp;quot;None&amp;quot; (removed)  then projection correctly assigns null. Feels like type converter is somehow affecting this. For now (will be changed in the future) project settings have &amp;quot;Convert nulled reference types to default value&amp;quot; checked. But unchecking it doesn&#x27;t seem to help anyway.&lt;/p&gt;&#xA;&lt;p&gt;Thank you!&lt;/p&gt;&#xA;</description>
					<author>Findev</author>
					<link>https://www.llblgen.com/tinyforum/Thread/29076#154606</link>
					<pubdate>Fri, 06 Mar 2026 21:11:49 GMT</pubdate>
					<category>Custom type converter and nullability in projection</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/29076#154606</guid>
				</item>
				<item>
					<title>Missing ModelInfoProviderSingleton by B Rightmer</title>
					<description>&lt;blockquote&gt;&lt;p class=&quot;quote-nickname&quot;&gt;Otis wrote:&lt;/p&gt;&#xA;&lt;blockquote&gt;&lt;p class=&quot;quote-nickname&quot;&gt;cadsjo wrote:&lt;/p&gt;&#xA;&lt;p&gt;Hi Otis,&lt;/p&gt;&#xA;&lt;p&gt;I think I found it.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;There are 2 new .csproj files generated.&lt;/strong&gt; &#xD;&#xA;I am going to use those.&#xD;&#xA;And there is a ModelInfoProviderSingleton class..&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;You might have missed the important remark about the migration of the csproj files. &lt;a href=&quot;https://www.llblgen.com/Documentation/5.10/LLBLGen%20Pro%20RTF/migratingcode.htm#migrating-generated-code-from-v5.3-to-v5.4&quot; rel=&quot;nofollow&quot;&gt;https://www.llblgen.com/Documentation/5.10/LLBLGen%20Pro%20RTF/migratingcode.htm#migrating-generated-code-from-v5.3-to-v5.4&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I have moved my files a couple different ways and only ever see one generated .vbproj file generated. And that project file doesn&#x27;t have a references to ModelInfoProviderSingleton. Is that a file of reference I can add to existing project?&lt;/p&gt;&#xA;</description>
					<author>B Rightmer</author>
					<link>https://www.llblgen.com/tinyforum/Thread/28692#154605</link>
					<pubdate>Fri, 06 Mar 2026 15:23:24 GMT</pubdate>
					<category>Missing ModelInfoProviderSingleton</category>
					<guid ispermalink="true">https://www.llblgen.com/tinyforum/Thread/28692#154605</guid>
				</item>
		</channel>
	</rss>
