WCF数据服务爆炸 - 非常重的负载 - 无论如何要避免所有混乱?

时间:2011-11-10 02:46:34

标签: xml silverlight web-services wcf-data-services odata

我正在使用WCF数据服务(v2),随着时间的推移,我的实体模型已经增长了很多,即超过100个实体。有很多可能的导航。客户端UI是具有数据输入和搜索屏幕的LOB应用程序。搜索表单带回数据集合,数据输入表单通常包含一个实体,该实体具有大多数属性但由于显示这些单独集合所需的组合框而具有许多导航属性(例如,带有显示一个组合框的组合框的员工数据输入表单)状态列表或部门列表。我懒加载组合框数据FYI。

我遇到的问题是,如果我想填充一个简单的列表(通过ComboBox),有效负载是很有用的!使用fiddler,例如,生成的XML有一堆杂乱,我真的不需要填充这个ComboBox。

以下是ONE记录被带回Employee类型的示例。

   ----------------------------- 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://localhost/HumanResourcesService.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Employees</title>
  <id>http://localhost/HumanResourcesService.svc/Employees</id>
  <updated>2011-11-09T23:41:01Z</updated>
  <link rel="self" title="Employees" href="Employees" />
  <entry>
    <id>http://localhost/HumanResourcesService.svc/Employees('54924')</id>
    <title type="text"></title>
    <updated>2011-11-09T23:41:01Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="Employee" href="Employees('54924')" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/EmployeeTypes" type="application/atom+xml;type=feed" title="EmployeeTypes" href="Employees('54924')/EmployeeTypes" /> 
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Locations" type="application/atom+xml;type=feed" title="Locations" href="Employees('54924')/Locations" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Buildings" type="application/atom+xml;type=feed" title="Buildings" href="Employees('54924')/Buildings" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Managers" type="application/atom+xml;type=feed" title="Managers" href="Employees('54924')/Managers" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Assignments" type="application/atom+xml;type=feed" title="Assignments" href="Employees('54924')/Assignments" />
    // ********************************************
    // MANY MORE LINKS - REMOVED FOR BREVITY
    // ********************************************        
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/xxx" type="application/atom+xml;type=entry" title="xxx" href="Employees('54924')/xxx" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/yyy" type="application/atom+xml;type=entry" title="yyy" href="Employees('54924')/yyy" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/zzz" type="application/atom+xml;type=entry" title="zzz" href="Employees('54924')/zzz" />
    <category term="xxx.HumanResources.Employee" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:EmpNo m:type="Edm.String">54924</d:EmpNo>
        <d:FirstName m:type="Edm.String">John</d:FirstName>
        <d:LastName m:type="Edm.String">Hughes</d:LastName>
        <d:MiddleName m:type="Edm.String">Michael</d:MiddleName>
        <d:Salary m:type="Edm.Decimal">20000</d:Salary>
        <d:Notes m:type="Edm.String">Anything...</d:Notes>
        <d:PrimaryPhone m:type="Edm.String">984-875-4545</d:PrimaryPhone>
        <d:StartDate m:type="Edm.DateTime">1977-02-01T00:00:00</d:StartDate>
        <d:EndDate m:type="Edm.DateTime">1995-12-31T00:00:00</d:EndDate>
        // ********************************************
        // MANY MORE PROPERTIES - REMOVED FOR BREVITY
        // ********************************************
        <d:AnotherFieldX m:type="Edm.Double" m:null="true" />
      </m:properties>
    </content>
  </entry>
</feed>

-----------------------------

正如你所看到的,我并不像那些LINKS那样需要那些垃圾,这只是一个实体。所有这些ComboBox都绑定到许多实体(范围从大约10到1000个记录)。你可以想象,所有这些额外的“喋喋不休”可以迅速打破我的服务。我想要的是在这种情况下显示一组员工姓名(ComboBoxes的许多类似案例)。

有没有人解决这个错综复杂的情景?我正在寻求一些建议。

4 个答案:

答案 0 :(得分:2)

如果您使用$ select:

,则不会序列化链接

答案 1 :(得分:1)

您是否尝试过JSON而不是XML? JSON的格式本质上更精简。您也可以(像其他人建议的那样)使用$ select = Query选项来限制返回的字段。

答案 2 :(得分:0)

您可以使用$ select查询选项仅投影您感兴趣的字段。在您的情况下,如果添加$ select = FirstName,LastName,您将看不到所有其他不需要的字段。

查看the documentation了解详情。我不记得如果你做一个投影,链接是否仍然是序列化的,所以你可能仍然有这个开销。

答案 3 :(得分:0)

您是否需要在OData服务中公开数据模型中的所有实体集?

如果只公开所需的实体集(calling SetEntitySetAccessRule once for each entity set that you need),则不会为数据服务未公开的任何实体生成rel链接。

另一方面,如果您需要工作单元中的所有相关实体,可能是您的数据模型过度规范化,您可以考虑对其进行非规范化。如果您已经使用$select来减小实体属性数据的大小,这可能会产生更少的整体XML,但我只是猜测这个,你需要测试它。

当然,(正如Leon建议的那样)JSON是OData最有效的线路格式,但WCF数据服务客户端库还不支持JSON。