Should DLinq support a read-only stream of objects?


Currently, when DLinq retrieves entities, it automatically inserts them in an identity cache. This ensures that if you run two queries whose results overlap, you get the same objects by reference – not copies. The object reference after all is the identity in CLR world. This ensures that when you change an entity, you don’t need to worry about which copy you are changing – there is only one. So update anomalies can be avoided. This comes at some minimal cost – hashing the object ref and maintaining the reference.


Of course, if you retrieve a projection – as a named, non-entity type or an anonymous type, you bypass the id cache and get read-only objects with no id enforcement.


So the questions are:
Is it interesting for you to get a stream of objects without id enforcement?


It makes sense if you can answer both the questions below affirmatively:
Do you have common, read-only and perhaps stream-only processing that you do with objects?
Do you need to use the entity types and cannot work with a projection or even the underlying DataReader (both give you an extra ounce of perf with less functionality)?


Comments (13)

  1. Ayende Raehin says:

    It makes sense.

    Common scenario: output data to a report / data grid (where you don’t want / need complex binding).

    I’m assuming that DLinq works in a way similar to NHibernate, and that the cache is limited to a session lifetime.

    If that is the case, I may make several queries from the same session in order to get the data. If all I’m doing with the data is binding to a few places, it would be good to have the data GCed ASAP rather than hang around until I’m done.

    what about just providing a way to clear the objects from the cache? Similiar to Including(), WithNoCaching() could be it.

  2. Roman Koreshkov says:

    I would see the case for Web Services or just for common integration frameworks based on XML.

    Suppose, you have a Web Service that returns an Order with its OrderLines, Discount and other details. For this service, you unlikely need id enforcement, if only you not utilize a shared (among multiple threads) cache of objects.

  3. Dinesh.Kulkarni says:

    Thanks Ayende and Roman.

    Roman, I understand the scenario but believe that it is covered under "projection" since in most of the web service cases, you would probably expose a subset of the entity only. That is already supported for fast streaming. I am looking to see if that is enough or not.

  4. dls says:

    I’d see the use to configure flyweights that do processing ( heavy on behavior, light on data), but I can believe that these are created by other means (e.g. MEnterprise Library’s ObjectBuilder). But it’d be nice to reconfigure those sorts of things through the data layer at times.

  5. Hi Dinesh,

    It makes sense in a scenario when you know that you will only be placing one query during the scope of the Identity Map.

    For example, say that you keep the Identity Map around for the scope of a Web Page, and you know that on a certain Web Page you will place exactly one query. In this situation, skipping the Identity Map would be an optimization. It might be a somewhat /dangerous/ optimization, since adding more queries or even updates to objects on that page would invalidate the assumption that bypassing the Identity Map is ok. Thus, it could be the kind of optimization you add once the development process has "settled" a bit, rather than something you do at the beginning of development.

    /Mats

  6. Hi again,

    >Roman, I understand the scenario but believe that it is covered under "projection" since in most of the web service cases, you would probably expose a subset of the entity only.<

    The problem with projection is that you miss out on business methods defined on the "real" objects. For example, a web service returning a list of orders might want to expose only a subset of the fields from the order objects, as you say, but may also rely on being able to expose the result of the GetTotal() method found only on the real order objects.

    /Mats

  7. Dinesh.Kulkarni says:

    It’s great to hear from you again Mats. I remember your visit to Microsoft from 2002 or 2003.

  8. Alexey Lavnikov says:

    The problem with Identity Cache is that it emulates Repeatable Read, while Projection derives Isolation mode from the connection (which is for performance reasons mostly Read-Commited) thus making calculations on aggregates inreliable.

    However, projections (if used properly) are really nice and handy feature of DLinq.

  9. Hackee says:

    It’s my opinion that Identity Map should not be used unless you as a programmer require it.You don’t pay if you do not explicitly request it:-) After all, the DLinq usage pattern encourages short-lived DataContext, so entity tracking service seems not so useful.

    Only after DataContext.Attach(entity) called does entity tracking service start watching the object graph of that entity.

  10. James Rutland says:

    Do you have common, read-only and perhaps stream-only processing that you do with objects?

    Yes big time. I have been a commercial app programmer for 18 years, reporting/query function points outnumber update scenarios 3 to 1.

    Do you need to use the entity types and cannot work with a projection or even the underlying DataReader (both give you an extra ounce of perf with less functionality)?

    Yes. For synthesized attributes I want that synthesis logic to be hosted in the entity class.

    Having written a small in-house OR/M I expect there will be further performance savings because change tracking logic within the Dlinq framework could be disabled for read-only streams, so isn’t this more than cache/identity issue?

  11. Skup says:

    The possibility of defining readonly streams would allow performance improvement for large scale web applications with a lot of report. Having to use projection to avoid caching is not that intuitive and you the lack the methods you added to your data objects. An option (you can reuse the ‘readonly’ keyword since it already exists !) would be welcome.