Inheritance Issue with Oracle XE

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for Oracle
Post Reply
ndroe
Posts: 18
Joined: Fri 03 Feb 2012 16:08

Inheritance Issue with Oracle XE

Post by ndroe » Thu 06 Dec 2012 18:39

I'm having an inheritance issue that only seems to happen in Oracle XE. I've tried this in both 7.2.104 and 7.3.132 versions. Here's my setup:

Code: Select all

    public class Parent
    {
        public int Id { get; set; }
        public virtual Child Child { get; set; }
        public int ChildId { get; set; }
    }

    public class Child
    {
        public int Id { get; set; }
    }

    public class SubChild : Child
    {}

    public class TestDbContext : DbContext
    {
        public IDbSet<Parent> Parents
        {
            get { return Set<Parent>(); }
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<ColumnTypeCasingConvention>();
            modelBuilder.Conventions.Remove<IncludeMetadataConvention>();

            var parentConfig = modelBuilder.Entity<Parent>();
            parentConfig.HasKey(p => p.Id);
            parentConfig.HasRequired(p => p.Child)
                        .WithMany()
                        .HasForeignKey(p => p.ChildId);
            parentConfig.Property(p => p.ChildId)
                        .HasColumnName("ChildId");
            modelBuilder.Entity<Child>()
                        .HasKey(c => c.Id);
            var subChildConfig = modelBuilder.Entity<SubChild>();
            subChildConfig.HasKey(s => s.Id);
            subChildConfig.ToTable("SubChildren");
        }
    }

    class Program
    {
        private static void Main(string[] args)
        {
            new Devart.Data.Oracle.OracleMonitor {IsActive = true};

            int parentId;

            using (var context = new TestDbContext())
            {
                var parent = new Parent
                    {
                        Child = new Child()
                    };
                context.Parents.Add(parent);
                context.SaveChanges();
                parentId = parent.Id;
            }

            using (var context = new TestDbContext())
            {
                var parent = context.Parents
                                    .Include(p => p.Child)
                                    .Single(p => p.Id == parentId);

                Console.WriteLine("Child is a " + parent.Child.GetType());
                Console.ReadKey();
            }
        }
    }
In Oracle Standard, this code correctly prints out "Child is a Child". However, in Oracle XE this code prints out "Child is a SubChild". Is this a known issue? Using the DBMonitor I verified that the SQL that gets executed against the database is the exact same in Standard and XE.

Thanks,
Nathan

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Inheritance Issue with Oracle XE

Post by Shalex » Mon 10 Dec 2012 14:05

ndroe wrote:Using the DBMonitor I verified that the SQL that gets executed against the database is the exact same in Standard and XE.
We consider that this is a bug of Oracle XE.

ndroe
Posts: 18
Joined: Fri 03 Feb 2012 16:08

Re: Inheritance Issue with Oracle XE

Post by ndroe » Tue 11 Dec 2012 02:39

I don't understand. Are you expecting Oracle XE to generate different SQL?

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Inheritance Issue with Oracle XE

Post by Shalex » Thu 20 Dec 2012 13:26

SQL is generated by our provider, and it is the same in both cases (Standard and XE) - dotConnect for Oracle works correctly. The difference is in the data which are stored in the database and returned to provider by Oracle XE.
Could you please compare the data, which are stored in Oracle Standard, with the data, which are stored in Oracle XE, with the same code?

ndroe
Posts: 18
Joined: Fri 03 Feb 2012 16:08

Re: Inheritance Issue with Oracle XE

Post by ndroe » Thu 20 Dec 2012 15:45

I confirmed this does appear to be a bug in Oracle XE. Here's the SQL that's being generated:

Code: Select all

SELECT
"Limit1"."Id",
"Limit1"."ChildId",
"Limit1".C1,
"Limit1"."Id1"
FROM ( SELECT
	"Extent1"."Id",
	"Extent1"."ChildId",
	"Join1"."Id1",
	CASE WHEN "Join1"."Id1" IS NULL THEN TO_CHAR(NULL) WHEN  NOT (("Join1".C1 = 1) AND ("Join1".C1 IS NOT NULL)) THEN '2X' ELSE '2X0X' END AS C1
	FROM  "Parents" "Extent1"
	LEFT OUTER JOIN  (SELECT
		"Extent2"."Id" AS "Id1",
		"Project1"."Id" AS "Id2",
		"Project1".C1
		FROM  "Children" "Extent2"
		LEFT OUTER JOIN  (SELECT
			"Extent3"."Id",
			1 AS C1
			FROM "SubChildren" "Extent3" ) "Project1" ON "Extent2"."Id" = "Project1"."Id" ) "Join1" ON "Extent1"."ChildId" = "Join1"."Id1"
	WHERE ("Extent1"."Id" = 1) AND ROWNUM <= 2
)  "Limit1"
The problem appears to be with the case statement. In Oracle XE when the case statement is included, "Join1".C1 is 1. When you take the case statement out, "Join1".C1 is null.

Post Reply