WCF 数据服务爆炸 - 有效负载非常重 - 无论如何要避免所有混乱?
我正在使用 WCF 数据服务 (v2),并且我的实体模型随着时间的推移已经增长了不少,即超过 100 个实体。有相当多的导航是可能的。客户端 UI 是具有数据输入和搜索屏幕的 LOB 应用程序。搜索表单带回数据集合,而数据输入表单通常由一个实体组成,该实体具有大部分属性,但由于需要组合框来显示这些单独的集合,因此具有许多导航属性(例如,带有显示单个集合的组合框的员工数据输入表单)州列表或部门列表。仅供参考,
我遇到的问题是,如果我想填充一个简单的列表(通过组合框),则有效负载非常大,例如,生成的 XML 有一堆混乱,我实际上并不需要填充此 ComboBox。
下面是一个返回 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>
-----------------------------
如您所见,我不需要所有这些垃圾。链接,这只是一个实体,所有这些 ComboBox 都绑定到许多实体(范围从大约 10 到 1000 条记录),正如您可以想象的那样,所有这些额外的“喋喋不休”很快就会消失。我想要的只是在这种情况下显示员工姓名的集合(组合框有许多类似的情况)。
有人解决过这个复杂的场景吗?我正在寻求一些建议。
I am using WCF Data Services (v2) and my Entity Model has grown quite a bit over time, i.e. over 100 entities. There is quite a bit of navigation that is possible. The client UIs are LOB applications with data entry and search screens. The search forms bring back collections of data and the data entry forms usually comprise of ONE entity that has the majority of the properties but with MANY navigation properties due to comboboxes needed to display these individual collections (e.g. an Employee data entry form with ComboBoxes displaying a State list or Department list. I lazy load the combobox data FYI.
The issue I am having is that if I want to populate a simple list (via a ComboBox), the payload is HUMONGOUS! Using fiddler, e.g., the XML generated has a bunch of clutter that I don't really NEED just to populate this ComboBox.
Here is an example of ONE record being brought back of type 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>
-----------------------------
As you can see, I don't need all that junk like those LINKS and this is just ONE entity. All of these ComboBoxes are bound to many entities (ranging anywhere from about 10 to 1000s of records). As you can imagine, all this extra "chatter" can quickly blow up my service. All I want is to display a collection of Employee Names in this case (many similar cases for ComboBoxes).
Has anyone tackled this convoluted scenario? I am seeking some recommendations.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您使用 $select,链接不会序列化:
Links aren't serialized if you use $select:
您是否尝试过 JSON 而不是 XML? JSON 的格式本质上更精简。您还可以(正如其他人建议的那样)使用 $select= Query 选项来限制返回的字段。
Have you tried JSON as opposed to XML? The formatting of JSON is inherently leaner. You can also (as others suggested) use the $select= Query option to limit the fields that are returned.
您可以使用 $select 查询选项仅投影您感兴趣的字段。在您的情况下,如果添加 $select=FirstName, LastName,您将不会看到所有其他不需要的字段。
查看文档了解更多详细信息。我不记得如果您进行投影,链接是否仍然被序列化,因此您可能仍然有这样的开销。
You can use the $select query option to project only the fields you are interested in. In your case, if you add $select=FirstName, LastName, you won't see all the other fields you don't need.
Check out the documentation for more details. I don't recall whether links are still serialized if you do a projection, so you may still have that overhead.
您是否需要通过 OData 服务公开数据模型中的所有实体集?
如果您仅公开所需的实体集(通过为每个实体集调用一次 SetEntitySetAccessRule您需要的),您将不会获得为数据服务未公开的任何实体生成的
rel
链接。另一方面,如果您的工作单元中需要所有这些相关实体,则可能是您的数据模型过度规范化,您可以考虑对其进行非规范化。如果您已经使用
$select
来减少实体属性数据的大小,这可能会生成较少的整体 XML,但我只是猜测这一点,您需要对其进行测试。当然,(正如 Leon 所建议的)JSON 是 OData 最有效的有线格式,但 WCF 数据服务客户端库尚不支持 JSON。
Do you need to have all the entity sets in your data model exposed by your OData service?
If you expose only the entity sets that you need (by calling SetEntitySetAccessRule once for each entity set that you need), you won't get a
rel
link generated for any entities not exposed by the data service.On the other hand, if you need all of those related entities in your unit of work, it might be that your data model is over-normalized, and you could consider denormalizing it a bit. If you are already using
$select
to reduce the size of entity property data, this might generate less overall XML, but I am only guessing about this and you would need to test it.Of course, (as Leon suggested) JSON is the most efficient wire format for OData, but the WCF Data Services client libraries don't yet support JSON.