我正在编写一个数据访问层,我想在其中仅返回每个请求所需的数据。假设您总共可以检索 100 个属性,但正常请求可能只需要其中的两到三个。
因此,我在请求中添加了一个参数,用于指定要返回的属性,并且只会从数据库中提取这些数据。
正常请求将返回 1,000 - 10,000 行的列表。我现在最关心的是如何高效地归还它们。
这些数据将在我的 .NET 项目中“内部”使用,但也可能被序列化为 XML 和 JSON,因此我不希望有 98 个空属性,而实际上只有 2 个属性填充了数据。
那么,创建此模型的最佳技术(在性能和“开销大小”的情况下)是什么?
更新:
所以一个属性实际上可以有三个状态。如果从未被要求,则应以某种方式将其删除,如果被要求,则应为 null 或实际值。
I'm writing a data access layer where I want to return just the data required for each request. Let's say there is a total of 100 properties that you could retrieve, but a normal request will probably just need two or three of them.
So I've added a parameter to the request that specifies the properties you want to return and only this data will be pulled from the DB.
A normal request will return a list of 1,000 - 10,000 rows. My big concern now is how to return them efficiently.
The data will be used "internally" in my .NET-project but may also be serialized to XML and JSON, and therefore I don't want to have 98 empty properties when in fact there is just 2 of them that are populated with data.
So, what would be the best technique (in case of performance and "overhead size") to use for creating this model?
Update:
So a property could actually have three states. If it never was asked for, it should somehow be removed, and if it was asked for it should be either null or the actual value.
发布评论
评论(2)
虽然我同意 Andrei 的回答很方便,它肯定会对性能产生影响。如果您的数据是扁平的(确实如此,因为您最终是从数据库中提取数据),那么您可以使用
IEnumerable>
其中IEnumerable
是一个IDictionary
包含该行中的值。一开始它比较笨重,但它是动态的;从结果集中添加或删除属性仍然有效。
它的性能也更高,因为您不会对反射(1,000 到 10,000)行进行
(1,000 到 10,000) * N
次调用,乘以N
,属性数量每行(如果每行有 100 个属性,则需要 100,000 到 1,000,000 次调用 Reflection,这将添加 向上)。 DynamicDictionary 最终将键/值对存储在查找表中,但它使用反射(通过 DLR 优化,但这仍然是其核心)来访问查找表。而且您确实知道这些属性是什么(您说过您正在项目内部使用它,因此您必须知道您想要使用的属性是什么)。为此,您确实应该使用强类型数据传输对象< /a> 具有所有可为空的属性,表示数据库中的值;结果集中任何 null 或不存在的内容都会设置为 null。结果集中不存在的值永远不会被设置。
这样,您就没有反射,可以获得编译时类型检查(这非常重要,使用
DynamicObject
将导致运行时异常)和更好的性能。使用这两种方法中的任何一种,XML 或 JSON 中的序列化都很简单,您只需序列化 null 值,或者根本不序列化属性(如果使用 XML,只需确保您的架构支持将元素作为选项)。
While I agree that Andrei's answer is convenient, it can definitely have a performance impact. If your data is flat (and it is, since you are ultimately pulling from a database), then you can have an
IEnumerable<IDictionary<string, object>>
where each row in theIEnumerable<T>
is aIDictionary<string, object>
contains the values from the row.It's a more unwieldy to begin with, but it is dynamic; the addition or removal of attributes from the result set will still work.
It's also more performant, in that you won't have
(1,000 to 10,000) * N
calls to reflection (1,000 to 10,000) rows, timesN
, the number of attributes on each row (if you have 100 attributes per row, then that's 100,000 to 1,000,000 calls to Reflection, which will add up). TheDynamicDictionary
ultimately stores the key/value pairs in a lookup table, but it uses Reflection (optimized through the DLR, but that's still at it's core) to get to the lookup table.And you do know what the properties are (you said you are using it internally for your project, so you have to know what the properties you want to use are). To that end, you really should be using a strongly-typed data transfer object with properties that are all nullable that represent the values from the database; anything that is null or doesn't exist in the result set gets set to null. Values that don't exist in the result set never get set.
This way, you have no Reflection, you get compile-time type checking (which is very important, using
DynamicObject
will result in run-time exceptions), and better performance.Serialization in XML or JSON is simple with either of these approaches, you simply serialize null values, or don't serialize the property at all (if using XML, just make sure that your schema supports the elements as being options).
考虑使用
DynamicDictionary
(请参阅System.Dynamic.DynamicObject
类),其中DynamicDictionary
派生自DynamicObject
类,能够获取/设置属性在运行时。它使用内部字典来存储属性及其值,因此您不会最终得到大量未使用的属性,并且访问时间应该没问题。用法非常简单
或者您可以使用
ExpandoObject< /code>
开箱即用,但它有点重,因为除了属性之外,它还允许您在此处存储事件和委托实例。
使用 XML/JSON 进行序列化/反序列化在这里应该不是问题。
Consider using
DynamicDictionary
(see the "Examples" section in the documentation for theSystem.Dynamic.DynamicObject
class) whereDynamicDictionary
is derived fromDynamicObject
class with ability to get/set properties in run-time.It uses internal dictionary to store properties and their values so you will not end up with a lot of unused properties and access time should be fine. The usage is a very simple
Or you can use
ExpandoObject
out of the box but it's a bit heavier because in addition to properties it allows you store events and instances of delegates here as well.Serialization/Deserialization with XML/JSON should not be a problem here.