Monday, December 24, 2007 3:49 AM
mtaulty
ADO.NET Data Services - LINQ to SQL and Associations
One of the things that I didn't mention (because I didn't know and I'm still not 100% sure :-)) in this post was what happens with associations when you're using ADO.NET Data Services and non-Entity Framework providers.
If you've got an Entity Framework data source exposing Customers and Orders then your metadata looks like this;
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Metadata>
<Schema Namespace="NorthwindModel" xmlns:dataWeb="http://schemas.microsoft.com/ado/2007/08/dataweb" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="NorthwindEntities" dataWeb:IsDefaultEntityContainer="true">
<EntitySet Name="Customers" EntityType="NorthwindModel.Customers" />
<EntitySet Name="Orders" EntityType="NorthwindModel.Orders" />
<AssociationSet Name="FK_Orders_Customers" Association="NorthwindModel.FK_Orders_Customers">
<End Role="Customers" EntitySet="Customers" />
<End Role="Orders" EntitySet="Orders" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Customers">
<Key>
<PropertyRef Name="CustomerID" />
</Key>
<Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
<Property Name="ContactName" Type="Edm.String" Nullable="true" MaxLength="30" Unicode="true" FixedLength="false" />
<Property Name="ContactTitle" Type="Edm.String" Nullable="true" MaxLength="30" Unicode="true" FixedLength="false" />
<Property Name="Address" Type="Edm.String" Nullable="true" MaxLength="60" Unicode="true" FixedLength="false" />
<Property Name="City" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="Region" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="PostalCode" Type="Edm.String" Nullable="true" MaxLength="10" Unicode="true" FixedLength="false" />
<Property Name="Country" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="Phone" Type="Edm.String" Nullable="true" MaxLength="24" Unicode="true" FixedLength="false" />
<Property Name="Fax" Type="Edm.String" Nullable="true" MaxLength="24" Unicode="true" FixedLength="false" />
<NavigationProperty Name="Orders" Relationship="NorthwindModel.FK_Orders_Customers" FromRole="Customers" ToRole="Orders" />
</EntityType>
<EntityType Name="Orders">
<Key>
<PropertyRef Name="OrderID" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="EmployeeID" Type="Edm.Int32" Nullable="true" />
<Property Name="OrderDate" Type="Edm.DateTime" Nullable="true" DateTimeKind="Unspecified" PreserveSeconds="true" />
<Property Name="RequiredDate" Type="Edm.DateTime" Nullable="true" DateTimeKind="Unspecified" PreserveSeconds="true" />
<Property Name="ShippedDate" Type="Edm.DateTime" Nullable="true" DateTimeKind="Unspecified" PreserveSeconds="true" />
<Property Name="ShipVia" Type="Edm.Int32" Nullable="true" />
<Property Name="Freight" Type="Edm.Decimal" Nullable="true" Precision="19" Scale="4" />
<Property Name="ShipName" Type="Edm.String" Nullable="true" MaxLength="40" Unicode="true" FixedLength="false" />
<Property Name="ShipAddress" Type="Edm.String" Nullable="true" MaxLength="60" Unicode="true" FixedLength="false" />
<Property Name="ShipCity" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="ShipRegion" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="ShipPostalCode" Type="Edm.String" Nullable="true" MaxLength="10" Unicode="true" FixedLength="false" />
<Property Name="ShipCountry" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false" />
<NavigationProperty Name="Customers" Relationship="NorthwindModel.FK_Orders_Customers" FromRole="Orders" ToRole="Customers" />
</EntityType>
<Association Name="FK_Orders_Customers">
<End Role="Customers" Type="NorthwindModel.Customers" Multiplicity="0..1" />
<End Role="Orders" Type="NorthwindModel.Orders" Multiplicity="*" />
</Association>
</Schema>
</Metadata>
Now, when you do the same thing with (say) LINQ to SQL then your metadata looks like this;
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Metadata>
<Schema Namespace="" xmlns:dataWeb="http://schemas.microsoft.com/ado/2007/08/dataweb" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityType Name="Customer">
<Key>
<PropertyRef Name="CustomerID" />
</Key>
<Property Name="CustomerID" Type="Edm.String" Nullable="false" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="CompanyName" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ContactName" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ContactTitle" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Address" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="City" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Region" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="PostalCode" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Country" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Phone" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Fax" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Orders" Type="Edm.String" Nullable="false" Unicode="true" FixedLength="false" MaxLength="Max" dataWeb:IsUri="true" dataWeb:UriType="Order" dataWeb:IsMultiValued="true" />
</EntityType>
<EntityType Name="Order">
<Key>
<PropertyRef Name="OrderID" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="CustomerID" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="EmployeeID" Type="Edm.Int32" Nullable="true" />
<Property Name="OrderDate" Type="Edm.DateTime" Nullable="true" PreserveSeconds="true" DateTimeKind="Unspecified" />
<Property Name="RequiredDate" Type="Edm.DateTime" Nullable="true" PreserveSeconds="true" DateTimeKind="Unspecified" />
<Property Name="ShippedDate" Type="Edm.DateTime" Nullable="true" PreserveSeconds="true" DateTimeKind="Unspecified" />
<Property Name="ShipVia" Type="Edm.Int32" Nullable="true" />
<Property Name="Freight" Type="Edm.Decimal" Nullable="true" Precision="19" Scale="4" />
<Property Name="ShipName" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ShipAddress" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ShipCity" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ShipRegion" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ShipPostalCode" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="ShipCountry" Type="Edm.String" Nullable="true" Unicode="true" FixedLength="false" MaxLength="Max" />
<Property Name="Customer" Type="Edm.String" Nullable="false" Unicode="true" FixedLength="false" MaxLength="Max" dataWeb:IsUri="true" dataWeb:UriType="Customer" dataWeb:IsMultiValued="false" />
</EntityType>
</Schema>
<Schema Namespace="northwindDataContext" xmlns:dataWeb="http://schemas.microsoft.com/ado/2007/08/dataweb" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="northwindDataContext" dataWeb:IsDefaultEntityContainer="true">
<EntitySet Name="Customers" EntityType="Customer" />
<EntitySet Name="Orders" EntityType="Order" />
</EntityContainer>
</Schema>
</Metadata>
Notice in the LINQ to SQL version we don't have any NavigationProperty and we don't have any Association. Notice also that the Orders property of Customer is of type String and is set to be a Uri and has a IsMultiValued = True.
What does this mean for the client-side generated code produced by webdatagen.exe?
Looking at the client-side code that corresponds to the Entity Framework version;
- Customers class has an Orders property of type Collection<Orders>
- Orders class has a Customers property of type Customers.
Looking at the client-side code that corresponds to the LINQ to SQL version;
- Customers class an an Orders property of type String.
- Orders class has an Orders property of type String.
So, the client-programming model looks to be a bit different depending on whether you're exposing Entity Framework providers or non-EF providers. I'm not sure whether you can somehow let the framework "know" that you have associations but, so far, I've not managed to find a way to do that.