EF and the crazy tester

I try to do some stupid EF tests.

From Northwind Product table, I did following inheritance:

<EntityType Name=Product>

    <Key>

        <PropertyRef Name=ProductID />

    </Key>

    <Property Name=ProductID Type=Int32 Nullable=false />

    <Property Name=ProductName Type=String Nullable=false MaxLength=40 Unicode=true FixedLength=false />

    <Property Name=SupplierID Type=Int32 />

    <Property Name=CategoryID Type=Int32 />

    <Property Name=QuantityPerUnit Type=String MaxLength=20 Unicode=true FixedLength=false />

    <Property Name=UnitPrice Type=Decimal Precision=19 Scale=4 />

    <Property Name=UnitsInStock Type=Int16 />

    <Property Name=UnitsOnOrder Type=Int16 />

</EntityType>

<EntityType Name=ProductReorder0 BaseType=NorthwindModel3.Product >

    <Property Name=Discontinued Type=Boolean Nullable=false />

</EntityType>

<EntityType Name=DiscontinuedProduct BaseType=NorthwindModel3.Product >

    <Property Name=ReorderLevel Type=Int16 Nullable=true />

</EntityType>

with this mapping:

<EntityTypeMapping TypeName=IsTypeOf(NorthwindModel3.ProductReorder0)>

    <MappingFragment StoreEntitySet=Products >

        <ScalarProperty Name=Discontinued ColumnName=Discontinued />

        <ScalarProperty Name=UnitsOnOrder ColumnName=UnitsOnOrder />

        <ScalarProperty Name=UnitsInStock ColumnName=UnitsInStock />

        <ScalarProperty Name=UnitPrice ColumnName=UnitPrice />

        <ScalarProperty Name=QuantityPerUnit ColumnName=QuantityPerUnit />

        <ScalarProperty Name=CategoryID ColumnName=CategoryID />

        <ScalarProperty Name=SupplierID ColumnName=SupplierID />

        <ScalarProperty Name=ProductName ColumnName=ProductName />

        <ScalarProperty Name=ProductID ColumnName=ProductID />

        <Condition ColumnName=ReorderLevel Value=0 />

    </MappingFragment>

</EntityTypeMapping>

<EntityTypeMapping TypeName=IsTypeOf(NorthwindModel3.DiscontinuedProduct)>

    <MappingFragment StoreEntitySet=Products >

        <ScalarProperty Name=ReorderLevel ColumnName=ReorderLevel />

        <ScalarProperty Name=UnitsOnOrder ColumnName=UnitsOnOrder />

        <ScalarProperty Name=UnitsInStock ColumnName=UnitsInStock />

        <ScalarProperty Name=UnitPrice ColumnName=UnitPrice />

        <ScalarProperty Name=QuantityPerUnit ColumnName=QuantityPerUnit />

        <ScalarProperty Name=CategoryID ColumnName=CategoryID />

        <ScalarProperty Name=SupplierID ColumnName=SupplierID />

        <ScalarProperty Name=ProductName ColumnName=ProductName />

        <ScalarProperty Name=ProductID ColumnName=ProductID />

        <Condition ColumnName=Discontinued Value=true />

    </MappingFragment>

</EntityTypeMapping>

<EntityTypeMapping TypeName=NorthwindModel3.Product>

    <MappingFragment StoreEntitySet=Products>

        <ScalarProperty Name=ProductID ColumnName=ProductID />

        <ScalarProperty Name=UnitsOnOrder ColumnName=UnitsOnOrder />

        <ScalarProperty Name=UnitsInStock ColumnName=UnitsInStock />

        <ScalarProperty Name=UnitPrice ColumnName=UnitPrice />

        <ScalarProperty Name=QuantityPerUnit ColumnName=QuantityPerUnit />

        <ScalarProperty Name=CategoryID ColumnName=CategoryID />

        <ScalarProperty Name=SupplierID ColumnName=SupplierID />

        <ScalarProperty Name=ProductName ColumnName=ProductName />

        <Condition ColumnName=Discontinued Value=false />

    </MappingFragment>

</EntityTypeMapping>


So in fact, what do I want to do?

What happens if ObjectContext don’t know which type instanciate? Indeed, with my DB, I have some products with Discontinued=true and ReorderLevel=0. So which type should ObjectContext instanciate? DiscontinuedProduct or ProductReorder0?

Of course, I have an EDM error but, as the compiler only use the generated code, I can work with this.

I execute following code for my test:

using (var context = new NorthwindEntities())

{

    var q = context.Products.OfType<DiscontinuedProduct>();

    foreach (var p in q)

        if (p.GetType() != typeof(Product))

            Console.WriteLine(p.GetType());

}

using (var context = new NorthwindEntities())

{

    var q = context.Products.OfType<ProductReorder0>();

    foreach (var p in q)

        if (p.GetType() != typeof(Product))

            Console.WriteLine(p.GetType());

}

using (var context = new NorthwindEntities())

{

    var q1 = context.Products.OfType<DiscontinuedProduct>();

    foreach (var p in q1)

        if (p.GetType() != typeof(Product))

            Console.WriteLine(p.GetType());

    var q2 = context.Products.OfType<ProductReorder0>();

    foreach (var p in q2)

        if (p.GetType() != typeof(Product))

            Console.WriteLine(p.GetType());

}

using (var context = new NorthwindEntities())

{

    var q = context.Products;

    foreach (var p in q)

        if (p.GetType() != typeof(Product))

            Console.WriteLine(p.GetType());

}


In the first two cases, there is no exception which is very interesting. This means that the OfType determines not only the sql request but also the entity instanciation.


In the third case, when I execute q2, we will have an exception. Indeed, the 3 entity types are linked to the same EntitySet. Each entity has an EntityKey which must be unique in the EntitySet. In the third case, the first Product with Discontinued = true and ReorderLevel = 0 will throw an exception.


In the last case, we will have an exception because ObjectContext doesn’t know which entity type instanciate.

This entry was posted in 7671, 7674, 7675. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>