Giter VIP home page Giter VIP logo

Comments (10)

JonathanMagnan avatar JonathanMagnan commented on July 28, 2024

Hello @bptillman ,

Thank you for reporting. My developer tried to reproduce the issue, but everything was working with him.

One major difference I can see in his code is that we were opening the connection, but since you are in a transaction, I would assume you do the same.

I'm coming back from vacation next Monday, so I will look with him next week.

Best Regards,

Jon

from entityframework-extensions.

bptillman avatar bptillman commented on July 28, 2024

@JonathanMagnan thank you for checking on this. I have done some more digging and I have found that this has actually has nothing to do with the session context value in my triggers and instead has to do with two other items causing the issue I'm seeing, depending on how they are set, and what version of this extension package that I am using, so I apologize for sending you down the rabbit hole of looking at that initially.

In my code, the EffectiveFromDate has a default SQL value set in our model builder like so:

public class MyDbContext : DbContext
{
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly)
			.ConfigureTemporalEntities();
	}
		
	ModelBuilder ConfigureTemporalEntities(this ModelBuilder modelBuilder)
	{
		var temporalEntityTypes = modelBuilder.Model.GetEntityTypes()
			.Where(x => x.ClrType.IsAssignableTo(typeof(ITemporal)));

		foreach (var entityType in temporalEntityTypes)
		{
			var effectiveFromDate = entityType.GetProperty(nameof(ITemporal.EffectiveFromDate))
				?? entityType.AddProperty(entityType.ClrType.GetProperty(nameof(ITemporal.EffectiveFromDate)));

			effectiveFromDate.SetDefaultValueSql("(sysutcdatetime())");
		}

		return modelBuilder;
	}
}

public interface ITemporal
{
	public DateTime EffectiveFromDate { get; set; }
}

public class Table1 : Entity<int>, ITemporal
{
	public Table1()
	{
	}

	public int Id { get; set; }
	public int ClientId { get; set; }
	public int TypeId { get; set; }
	public bool Deleted { get; set;}
	public int CreatedUserId { get; set; }
	public int UpdatedUserId { get; set; }
	public DateTime CreatedDate { get; set; }
	public DateTime EffectiveFromDate { get; set; }
	public string TagId { get; set; }
	public string SerialNumber { get; set; }
	public string Barcode { get; set; }
}

Having this in the code, plus having the Bulk Insert option for IncludeGraph being false appears to cause the issue of the date set in code not being persisted to the database on version 7.22.2.

I tested this out with the combinations of

  1. IncludeGraph = false, and SetDefaultValueSql being declared
  2. IncludeGraph = false, and SetDefaultValueSql not being declared
  3. IncludeGraph = true, and SetDefaultValueSql being declared
  4. IncludeGraph = true, and SetDefaultValueSql not being declared

Only under scenario 1 did I find that the value I set in my code for EffectiveFromDate not making it into the database.

Running Sql Profiler I was able to see why in that scenario, since the merge statement being run did not end up including EffectiveFromDate when IncludeGraph was false and the SetDefaultValueSql was declared, as you can see from this query I grabbed:

exec sp_executesql N'CREATE TABLE #ZZZProjects_8c31ee2f_6782_43c9_b431_fc149431c312z ( [$action] VARCHAR(100) NULL, ZZZ_Index INT NULL, [Id] [sys].[int] NULL );
MERGE INTO [dbo].[table1]  AS DestinationTable
USING
(
SELECT TOP 100 PERCENT * FROM (SELECT @0_0 AS [ClientId], @0_1 AS [TypeId], @0_2 AS [CreatedDate], @0_3 AS [CreatedUserId], @0_4 AS [SerialNumber], @0_5 AS [TagId], @0_6 AS [Deleted], @0_7 AS [ProductId], @0_8 AS [Barcode], @0_10 AS [UpdatedUserId], @0_11 AS [Id], @0_12 AS ZZZ_Index) AS StagingTable ORDER BY ZZZ_Index
) AS StagingTable
ON 1 = 2
WHEN NOT MATCHED THEN
    INSERT ( [ClientId], [TypeId], [CreatedDate], [CreatedUserId], [SerialNumber], [TagId], [Deleted], [ProductId], [Barcode], [UpdatedUserId] )
    VALUES ( [ClientId], [TypeId], [CreatedDate], [CreatedUserId], [SerialNumber], [TagId], [Deleted], [ProductId], [Barcode], [UpdatedUserId] )
OUTPUT
    $action,
    StagingTable.ZZZ_Index,
    INSERTED.[Id]
INTO #ZZZProjects_8c31ee2f_6782_43c9_b431_fc149431c312z

;
SELECT   A.* ,B.[Id] AS [Id_zzzinserted], B.[EffectiveFromDate] AS [EffectiveFromDate_zzzinserted], B.[EffectiveThruDate] AS [EffectiveThruDate_zzzinserted] FROM #ZZZProjects_8c31ee2f_6782_43c9_b431_fc149431c312z AS A
INNER JOIN [dbo].[table1] AS B  ON  A.[Id] = B.[Id]
;
DROP TABLE #ZZZProjects_8c31ee2f_6782_43c9_b431_fc149431c312z;',N'@0_0 int,@0_1 int,@0_2 datetime2(7),@0_3 int,@0_4 nvarchar(256),@0_5 nvarchar(256),@0_6 bit,@0_7 int,@0_8 varchar(512),@0_10 int,@0_11 int,@0_12 int',@0_0=135,@0_1=5,@0_2='2020-01-01 00:00:00',@0_3=0,@0_4=NULL,@0_5=NULL,@0_6=0,@0_7=1505,@0_8=NULL,@0_9=N'RFID-3b646811-563c-45c9-a5c4-d1a549685d0b',@0_10=0,@0_11=0,@0_12=0

Upon updating to 7.102.2.4 the behavior is different under the same 4 scenarios I mentioned above with IncludeGraph and the SetDefaultValueSql. On this newer version I see the following:

  1. IncludeGraph = false, and SetDefaultValueSql being declared - The incorrect date is persisted.
  2. IncludeGraph = false, and SetDefaultValueSql not being declared - The correct date is persisted.
  3. IncludeGraph = true, and SetDefaultValueSql being declared - The incorrect date is persisted.
  4. IncludeGraph = true, and SetDefaultValueSql not being declared - The correct date is persisted.

So you can see how now that as long as SetDefaultValueSql is declared, no matter if we use IncludeGraph = true or false, it does not persist the date we set it to.

We are re-evaluating the need to use SetDefaultValueSql in our code, but for now it is there and we end up needing to bulk insert different objects that have the EffectivefromDate columns with IncludeGraph = false and for others true.

from entityframework-extensions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.