這是我想做的事:OData服務不定製返回對象
我從那裏我需要得到數據的現有數據庫。
我創建了數據契約,通過使用實體框架將它們映射到相應的表。在我的例子中,我有三個表 - tblOrder,tblProduct和tblCustomer。所以我創建了三個數據契約映射到這些表。實體框架註釋已添加到數據對照中。我寫了一個單元測試來測試我的數據合同。一切都按照預期使用直接的實體框架調用。請參閱下面的單元測試1。
爲每個數據合同添加了DataServiceKey註釋。並通過添加訂單上下文和數據服務svc將它們包裝在OData服務中。見下文。
寫了一個單元測試,通過OData服務訪問一些現有的訂單數據。問題:OData服務僅返回Order對象上的非自定義數據類型。它在custome數據類型字段(如CustomerInfo和ProductList)上返回null。
我做錯了什麼?對於使用EF進行檢索的OData調用來處理對象,有什麼特別之處嗎?
[DataServiceKey("ID")]
[Table("tblOrder", Schema = "schOnlineSale")]
public class Order
{
[Column("OrderId"), Key]
public int ID { get; set; }
public string OrderName { get; set; }
public int CustomerId { get; set; }
[ForeignKey("CustomerId")]
public virtual Customer CustomerInfo { get; set; }
[ForeignKey("OrderId")]
public virtual ICollection<Product> ProductList{ get; set; }
}
[DataServiceKey("CustomerId")]
[Table("tblCustomer", Schema = "schOnlineSale")]
public class Customer
{
[Key]
public int CustomerId{ get; set; }
[Column("FullName")]
public string Name { get; set; }
public string MailingAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZIPCode { get; set; }
}
[DataServiceKey("ProductId")]
[Table("tblProduct", Schema = "schOnlineSale")]
public class Product
{
[Key]
public int ProductId{ get; set; }
public int OrderId{ get; set; }
public string ProductName { get; set; }
public decimal SalePrice { get; set; }
}
//OData Service wrapper classes
public class OrderContext: DbContext
{
public DbSet<Order> Orders {get; set;}
public DbSet<Product> Products {get; set;}
}
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class OrderDataService : DataService<OrderContext>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
config.SetEntitySetAccessRule("Products", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.UseVerboseErrors = true;
}
protected override void HandleException(HandleExceptionArgs args)
{
try
{
args.UseVerboseErrors = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
protected override OrderContext CreateDataSource()
{
var dataSource = new OrderContext();
dataSource.Configuration.ProxyCreationEnabled = false;
return dataSource;
}
}
//Unit Test 1 - Querying via data context directly
public void EFDataContext_GetOrderTest()
{
var context = new OrderContext();
var list = (from a in context.Orders
where a.OrderId == 10 ||
a.OrderId == 15 ||
a.OrderId== 20 select a).ToList();
//CustomerInfo and ProductList values are populated properly
}
//Unit test 2 - Querying via OData Service
public void OData_GetOrderTest()
{
string uriString = "http://localhost/OrderServices/OrderDataService.svc/Orders(10)";
Uri serviceUri = new Uri(uriString);
OrderContext context = new OrderContext(serviceUri);
context.IgnoreResourceNotFoundException = true;
var orderList = context.Orders;
foreach (Order s in orderList)
{
TestContext.WriteLine("OrderId=" + s.ID);
Assert.IsNotNull(s.CustomerInfo); //CustomerInfo is not returned with OData call
//but it's returned properly with entity framework call.
foreach (Product p in s.ProductList)
{
//ProductList is also not returned with OData Service call,
//but it is returned properly when accessing through Entity Framework calls
//directly
}
}
}
//app.config
<configuration>
<connectionStrings>
<add name="OrderContext" connectionString="a valid connection string" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
這個問題似乎在於我們將ProxyCreationEnabled設置爲false,如果我們在我們的簡單數據訪問單元測試中這樣做,訂單不再加載。我們已經嘗試使用Expand選項已經和LazyLoadingEnabled = false一起使用,但是我們仍然沒有獲得Expand,如果我們將ProxyCreationEnabled變回true,那麼URL將不再拉上來。我們如何強制EF加載訂單而不將ProxyCreationEnabled設置爲true? – dariusriggins
也嘗試應用此修補程序,但它沒有解決問題,如果我離開代理生成。 http://support.microsoft.com/kb/2277657 – dariusriggins
你可以嘗試追蹤線路上的請求/響應,例如使用fiddler來查看響應是否包含擴展的實體(假設您使用客戶)? –