Quantcast
Channel: entityframework Discussions Rss Feed
Viewing all articles
Browse latest Browse all 1793

New Post: Bug in TPT inheritance of EF6-beta1?

$
0
0
Hi,

Lately I've been testing EF6 and I must say I'm very impressed with all the improvements! Can't wait for the RTM version to be shipped.

While testing with EF6-Beta1 I think I found a bug. It's easy to reproduce.

My database has 2 tables crm.Relation and history.Relation table, the history.Relation table contains the same set of fields as the crm.Relation table (for auditing changes) as well as a VersionId field (int) and an UpdatedOn field (datetime).

Entities are defined as:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;

namespace POC_TablePerType
{
    public interface IMyDbContext : IDisposable
    {
        IDbSet<crm_Relatie> crm_Relatie { get; set; } // Relatie
        IDbSet<crm_RelatieHistorie> crm_RelatieHistorie { get; set; } // RelatieHistorie

        int SaveChanges();
    }

    public partial class MyDbContext : DbContext, IMyDbContext
    {
        public IDbSet<crm_Relatie> crm_Relatie { get; set; } 
        public IDbSet<crm_RelatieHistorie> crm_RelatieHistorie { get; set; }

        static MyDbContext()
        {
            Database.SetInitializer<MyDbContext>(null);
        }

        public MyDbContext() : base("Name=MyDbContext") { }
        public MyDbContext(string connectionString) : base(connectionString)  { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Configurations.Add(new crm_RelatieConfiguration());
            modelBuilder.Configurations.Add(new crm_RelatieHistorieConfiguration());
        }
    }

    public partial class crm_Relatie
    {
        public int RelatieId { get; set; }
        public string Zoeksleutel { get; set; }
        public string Relatienaam { get; set; }
        public crm_Relatie() { }
    }

    internal partial class crm_RelatieConfiguration : EntityTypeConfiguration<crm_Relatie>
    {
        public crm_RelatieConfiguration()
        {
            ToTable("crm.Relatie");
            HasKey(x => x.RelatieId);

            Property(x => x.RelatieId).HasColumnName("RelatieID").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            Property(x => x.Zoeksleutel).HasColumnName("Zoeksleutel").IsRequired().HasMaxLength(5);
            Property(x => x.Relatienaam).HasColumnName("Relatienaam").IsRequired().HasMaxLength(40);
        }
    }

    public class crm_RelatieHistorie : crm_Relatie
    {
        public int VersieId { get; set; }
        public DateTime GewijzigdOp { get; set; }
    }

    internal partial class crm_RelatieHistorieConfiguration : EntityTypeConfiguration<crm_RelatieHistorie>
    {
        public crm_RelatieHistorieConfiguration()
        {
            ToTable("history.Relatie");
            HasKey(x => new { x.RelatieId, x.VersieId });
        }
    }
}
Tables are created as:
CREATE TABLE [crm].[Relatie](
    [RelatieID] [int] IDENTITY(1,1) NOT NULL,
    [Zoeksleutel] [nchar](5) NOT NULL,
    [Relatienaam] [nvarchar](40) NOT NULL,
    [fkContactpersoonID] [int] NULL,
    [fkVerantwoordelijkeRAID] [int] NULL,
 CONSTRAINT [PK_Relatie] PRIMARY KEY CLUSTERED 
(
    [RelatieID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [history].[Relatie](
    [GewijzigdOp] [datetime] NOT NULL,
    [VersieID] [int] NOT NULL,
    [RelatieID] [int] NOT NULL,
    [Zoeksleutel] [nchar](5) NOT NULL,
    [Relatienaam] [nvarchar](40) NOT NULL,
 CONSTRAINT [PK_Relatie] PRIMARY KEY CLUSTERED 
(
    [RelatieID] ASC,
    [VersieID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [HISTORY]
) ON [HISTORY]
The problem is easy to see when I run this code:
            using (var db = new MyDbContext())
            {
                Console.WriteLine("Selecting just the fields I need:");
                /* Runs this query:
                     SELECT 
                        [Extent1].[RelatieID] AS [RelatieID], 
                        [Extent1].[VersieId] AS [VersieId], 
                        [Extent2].[Relatienaam] AS [Relatienaam]
                        FROM  [history].[Relatie] AS [Extent1]
                        INNER JOIN [crm].[Relatie] AS [Extent2] ON [Extent1].[RelatieID] = [Extent2].[RelatieID]
                 */
                var relaties = from r in db.crm_RelatieHistorie
                    select new {r.RelatieId, r.VersieId, r.Relatienaam};
                foreach (var rel in relaties)
                    Console.WriteLine(String.Format("Name: {0}\tVersion: {1}",rel.Relatienaam, rel.VersieId));

                Console.WriteLine("\nSelecting the object itself:");
                /* Runs this query:
                     SELECT 
                        '0X0X' AS [C1], 
                        [Extent1].[RelatieID] AS [RelatieID], 
                        [Extent2].[Zoeksleutel] AS [Zoeksleutel], 
                        [Extent2].[Relatienaam] AS [Relatienaam], 
                        [Extent1].[VersieId] AS [VersieId], 
                        [Extent1].[GewijzigdOp] AS [GewijzigdOp]
                        FROM  [history].[Relatie] AS [Extent1]
                        INNER JOIN [crm].[Relatie] AS [Extent2] ON [Extent1].[RelatieID] = [Extent2].[RelatieID]
                 */
                var relaties2 = from r in db.crm_RelatieHistorie select r;
                foreach (var rel in relaties2)
                    Console.WriteLine(String.Format("Name: {0}\tVersion: {1}", rel.Relatienaam, rel.VersieId));
            }
            Console.ReadLine();
        }
Althought both queries (see comments in code) are almost equal, they show different results:
Selecting just the fields I need:
Name: A company     Version: 1
Name: B company     Version: 1
Name: C company     Version: 1
Name: D company     Version: 1
Name: Customer-With-4-Versions   Version: 1
Name: Customer-With-4-Versions   Version: 2
Name: Customer-With-4-Versions   Version: 3
Name: Customer-With-4-Versions   Version: 4

Selecting the object itself:
Name: A company     Version: 1
Name: B company     Version: 1
Name: C company     Version: 1
Name: D company     Version: 1
Name: Customer-With-4-Versions   Version: 1
Name: Customer-With-4-Versions   Version: 1
Name: Customer-With-4-Versions   Version: 1
Name: Customer-With-4-Versions   Version: 1
The history table contains 4 different versions of the last customer so the former output is correct whereas the latter incorrectly shows version 1 for each instance.

When I capture the queries and run them on the database, each record of the last customer correctly shows another version, no duplicate versionnumbers for it.

That's why I think this is a bug that should be fixed. I'm using .NET 4.5, VS2012 Update 3, EF 6.0.0.0 and SQL Server 2012. Can anyone confirm that this is indeed a bug?

UPDATE:
When I change the content of the second foreach to:
   Console.WriteLine(String.Format("Name: {0}\tVersion: {1}", rel.Relatienaam, rel.VersieId));
   if (rel.VersieId == 1) rel.VersieId = 10;
the output becomes:
Selecting just the fields I need:
Name: A company     Version: 1
Name: B company     Version: 1
Name: C company     Version: 1
Name: D company     Version: 1
Name: Customer-With-4-Versions   Version: 1
Name: Customer-With-4-Versions   Version: 2
Name: Customer-With-4-Versions   Version: 3
Name: Customer-With-4-Versions   Version: 4

Selecting the object itself:
Name: A company     Version: 1
Name: B company     Version: 1
Name: C company     Version: 1
Name: D company     Version: 1
Name: Customer-With-4-Versions   Version: 1
Name: Customer-With-4-Versions   Version: 10
Name: Customer-With-4-Versions   Version: 10
Name: Customer-With-4-Versions   Version: 10
Looks like some some invalid reference to an entity instance.
Perhaps this helps to find the rootcause.

Best regards,
Jeroen

Viewing all articles
Browse latest Browse all 1793

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>