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>
(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>