2
Vote

Conventional builder should throw error when it cannot find a key for an entity type.

description

In this scenario, I generated a DbFirst model from Northwind database. For the following 2 classes which were autogenerated, the model builder is not able to figure out the keys(as expected), but the metadata is produced without any errors and with no keys for those entity types. I found the error when I was trying to generate a proxy where it complained about keys not being present. I think we should throw error upfront for this kind of scenario.

(I also tested with a simple CodeFirst scenario having a class similar to CustomDemograhic below.)

Autogenerated classes from Northwind

public partial class CustomerDemographic
{
    public CustomerDemographic()
    {
        this.Customers = new HashSet<Customer>();
    }

    public string CustomerTypeID { get; set; }
    public string CustomerDesc { get; set; }

    public virtual ICollection<Customer> Customers { get; set; }
}
public partial class Order_Detail
{
    public int OrderID { get; set; }
    public int ProductID { get; set; }
    public decimal UnitPrice { get; set; }
    public short Quantity { get; set; }
    public float Discount { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

Model

static IEdmModel GetImplicitEdmModel()
    {
        ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();

        modelBuilder.EntitySet<Product>("Products");
        modelBuilder.EntitySet<Category>("Categories");
        modelBuilder.EntitySet<Customer>("Customers");
        modelBuilder.EntitySet<Order>("Orders");
        modelBuilder.EntitySet<Order_Detail>("OrderDetails");
        modelBuilder.EntitySet<CustomerDemographic>("CustomerDemographics");
        modelBuilder.EntitySet<Employee>("Employees");
        modelBuilder.EntitySet<Region>("Regions");
        modelBuilder.EntitySet<Shipper>("Shippers");
        modelBuilder.EntitySet<Supplier>("Suppliers");
        modelBuilder.EntitySet<Territory>("Territories");

        return modelBuilder.GetEdmModel();
    }

Metadata

<EntityType Name="Order_Detail">
    <Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
    <Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
    <Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" />
    <Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
    <Property Name="Discount" Type="Edm.Single" Nullable="false" />
    <NavigationProperty Name="Order" Relationship="ODataServiceWeb.ODataServiceWeb_Order__Detail_Order_ODataServiceWeb_Order_OrderPartner" ToRole="Order" FromRole="OrderPartner" />
    <NavigationProperty Name="Product" Relationship="ODataServiceWeb.ODataServiceWeb_Order__Detail_Product_ODataServiceWeb_Product_ProductPartner" ToRole="Product" FromRole="ProductPartner" />
  </EntityType>

  <EntityType Name="CustomerDemographic">
    <Property Name="CustomerTypeID" Type="Edm.String" />
    <Property Name="CustomerDesc" Type="Edm.String" />
    <NavigationProperty Name="Customers" Relationship="ODataServiceWeb.ODataServiceWeb_CustomerDemographic_Customers_ODataServiceWeb_Customer_CustomersPartner" ToRole="Customers" FromRole="CustomersPartner" />
  </EntityType>

comments

HongmeiG wrote Oct 18, 2012 at 9:40 PM

We can do this at the model validation pass.

hannespreishuber wrote Feb 3 at 8:04 AM

I am curios about the comment from hongmeig.
Kichalla have made a very detailed bug Report, and the only comment is a cryptic small sentence month later?

I want to add
1) ist a breaking Feature Prio High
2) expected result is a <Key> Element like odata specs sayshttp://www.odata.org/blog/2011/10/14/vocabularies-in-odata

HongmeiG wrote Mar 30 at 12:11 AM

Apology on being not clear earlier. Before conventional model builder builds the model, we can actually do a validation pass to see if the model we are going to build is valid.

For example, in Kiran's case, if the key is missing for a entitySet, we should easily detect that and throw.

Hope this clarifies.