Problem in ADO.Net Data Service when working with Entity Model
I am just trying to learn ADO.Net Data servicesWCF Data Services.
I have just created a sample program where I have Entity Data Model of Northwind database and I have grabbed Products, Category and Supplier entities in my entity model.
Then I have added a class which looks like
[DataServiceKey("ProductID")]
public class ProductsService
{
public ProductsService()
{
}
public IQueryable<Product> Products
{
get
{
NORTHWNDEntities db = new NORTHWNDEntities();
return db.Products.AsQueryable();
}
}
}
Then I have a WCF Data service file which looks like
public class ProductsDataService : DataService<ProductsService>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
I know I can use the NorthwindDataEntities
class then it works but if I try to use my ProductsService class, I get Request Error problem ...
Any idea what's going wrong here please...
The autogenerated Product class is as follows, I have added DataServiceKey attribute..
[EdmEntityTypeAttribute(NamespaceName="NORTHWNDModel", Name="Product")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
[DataServiceKey("ProductID")]
public partial class Product : EntityObject
{
#region Factory Method
public static Product CreateProduct(global::System.Int32 productID, global::System.String productName, global::System.Boolean discontinued)
{
Product product = new Product();
product.ProductID = productID;
product.ProductName = productName;
product.Discontinued = discontinued;
return product;
}
#endregion
#region Primitive Properties
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[DataMemberAttribute()]
public global::System.Int32 ProductID
{
get
{
return _ProductID;
}
set
{
if (_ProductID != value)
{
OnProductIDChanging(value);
ReportPropertyChanging("ProductID");
_ProductID = StructuralObject.SetValidValue(value);
ReportPropertyChanged("ProductID");
OnProductIDChanged();
}
}
}
private global::System.Int32 _ProductID;
partial void OnProductIDChanging(global::System.Int32 value);
partial void OnProductIDChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.String ProductName
{
get
{
return _ProductName;
}
set
{
OnProductNameChanging(value);
ReportPropertyChanging("ProductName");
_ProductName = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("ProductName");
OnProductNameChanged();
}
}
private global::System.String _ProductName;
partial void OnProductNameChanging(global::System.String value);
partial void OnProductNameChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.Int32> SupplierID
{
get
{
return _SupplierID;
}
set
{
OnSupplierIDChanging(value);
ReportPropertyChanging("SupplierID");
_SupplierID = StructuralObject.SetValidValue(value);
ReportPropertyChanged("SupplierID");
OnSupplierIDChanged();
}
}
private Nullable<global::System.Int32> _SupplierID;
partial void OnSupplierIDChanging(Nullable<global::System.Int32> value);
partial void OnSupplierIDChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.Int32> CategoryID
{
get
{
return _CategoryID;
}
set
{
OnCategoryIDChanging(value);
ReportPropertyChanging("CategoryID");
_CategoryID = StructuralObject.SetValidValue(value);
ReportPropertyChanged("CategoryID");
OnCategoryIDChanged();
}
}
private Nullable<global::System.Int32> _CategoryID;
partial void OnCategoryIDChanging(Nullable<global::System.Int32> value);
partial void OnCategoryIDChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public global::System.String QuantityPerUnit
{
get
{
return _QuantityPerUnit;
}
set
{
OnQuantityPerUnitChanging(value);
ReportPropertyChanging("QuantityPerUnit");
_QuantityPerUnit = StructuralObject.SetValidValue(value, true);
ReportPropertyChanged("QuantityPerUnit");
OnQuantityPerUnitChanged();
}
}
private global::System.String _QuantityPerUnit;
partial void OnQuantityPerUnitChanging(global::System.String value);
partial void OnQuantityPerUnitChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.Decimal> UnitPrice
{
get
{
return _UnitPrice;
}
set
{
OnUnitPriceChanging(value);
ReportPropertyChanging("UnitPrice");
_UnitPrice = StructuralObject.SetValidValue(value);
ReportPropertyChanged("UnitPrice");
OnUnitPriceChanged();
}
}
private Nullable<global::System.Decimal> _UnitPrice;
partial void OnUnitPriceChanging(Nullable<global::System.Decimal> value);
partial void OnUnitPriceChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.Int16> UnitsInStock
{
get
{
return _UnitsInStock;
}
set
{
OnUnitsInStockChanging(value);
ReportPropertyChanging("UnitsInStock");
_UnitsInStock = StructuralObject.SetValidValue(value);
ReportPropertyChanged("UnitsInStock");
OnUnitsInStockChanged();
}
}
private Nullable<global::System.Int16> _UnitsInStock;
partial void OnUnitsInStockChanging(Nullable<global::System.Int16> value);
partial void OnUnitsInStockChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.Int16> UnitsOnOrder
{
get
{
return _UnitsOnOrder;
}
set
{
OnUnitsOnOrderChanging(value);
ReportPropertyChanging("UnitsOnOrder");
_UnitsOnOrder = StructuralObject.SetValidValue(value);
ReportPropertyChanged("UnitsOnOrder");
OnUnitsOnOrderChanged();
}
}
private Nullable<global::System.Int16> _UnitsOnOrder;
partial void OnUnitsOnOrderChanging(Nullable<global::System.Int16> value);
partial void OnUnitsOnOrderChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.Int16> ReorderLevel
{
get
{
return _ReorderLevel;
}
set
{
OnReorderLevelChanging(val开发者_运维百科ue);
ReportPropertyChanging("ReorderLevel");
_ReorderLevel = StructuralObject.SetValidValue(value);
ReportPropertyChanged("ReorderLevel");
OnReorderLevelChanged();
}
}
private Nullable<global::System.Int16> _ReorderLevel;
partial void OnReorderLevelChanging(Nullable<global::System.Int16> value);
partial void OnReorderLevelChanged();
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.Boolean Discontinued
{
get
{
return _Discontinued;
}
set
{
OnDiscontinuedChanging(value);
ReportPropertyChanging("Discontinued");
_Discontinued = StructuralObject.SetValidValue(value);
ReportPropertyChanged("Discontinued");
OnDiscontinuedChanged();
}
}
private global::System.Boolean _Discontinued;
partial void OnDiscontinuedChanging(global::System.Boolean value);
partial void OnDiscontinuedChanged();
#endregion
#region Navigation Properties
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("NORTHWNDModel", "FK_Products_Categories", "Categories")]
public Category Category
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Category>("NORTHWNDModel.FK_Products_Categories", "Categories").Value;
}
set
{
((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Category>("NORTHWNDModel.FK_Products_Categories", "Categories").Value = value;
}
}
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[BrowsableAttribute(false)]
[DataMemberAttribute()]
public EntityReference<Category> CategoryReference
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Category>("NORTHWNDModel.FK_Products_Categories", "Categories");
}
set
{
if ((value != null))
{
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Category>("NORTHWNDModel.FK_Products_Categories", "Categories", value);
}
}
}
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("NORTHWNDModel", "FK_Order_Details_Products", "Order_Details")]
public EntityCollection<Order_Detail> Order_Details
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Order_Detail>("NORTHWNDModel.FK_Order_Details_Products", "Order_Details");
}
set
{
if ((value != null))
{
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Order_Detail>("NORTHWNDModel.FK_Order_Details_Products", "Order_Details", value);
}
}
}
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("NORTHWNDModel", "FK_Products_Suppliers", "Suppliers")]
public Supplier Supplier
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Supplier>("NORTHWNDModel.FK_Products_Suppliers", "Suppliers").Value;
}
set
{
((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Supplier>("NORTHWNDModel.FK_Products_Suppliers", "Suppliers").Value = value;
}
}
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[BrowsableAttribute(false)]
[DataMemberAttribute()]
public EntityReference<Supplier> SupplierReference
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Supplier>("NORTHWNDModel.FK_Products_Suppliers", "Suppliers");
}
set
{
if ((value != null))
{
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Supplier>("NORTHWNDModel.FK_Products_Suppliers", "Suppliers", value);
}
}
}
#endregion
}
You didn't show us your Product
class - that class needs to have the [DataServiceKey("ProductID")]
on it - in order to make it clear to the DataService how to identify a product:
[DataServiceKey("ProductID")]
public partial class Product
{
public int ProductID { get; set; }
...
}
With this, I think your approach should work.
If not: please let us know what the exact error is!
Without the exact error it's hard to guess what the actual problem is. But in general this will not work. The reason is the difference in behavior of IQueryable between the LINQ to EF and LINQ to Objects. If you specify the ObjectContext (NorthwindEntities in your case) as the context for the data service, the WCF Data Services assume LINQ to EF behavior and generates the queries in such a way that LINQ to EF can handle it. If you specify a non-ObjectContext class (your own in this case) as the context for the data service, it assumes LINQ to Objects behavior and generates somewhat different queries. The main difference is null propagation (LINQ to Objects requires explicit null propagation, while LINQ to EF doesn't like it and handles it implicitely), but there are other smaller differences as well. Do you really need to use your own class as the context and not the EF generated ObjectContext based class?
精彩评论