DCSIMG
October 2008 - Posts - Ido Flatow's Blog Veni Vidi Scripsi

Ido Flatow's Blog

Veni Vidi Scripsi

News

Have you heard me speak?
Powered
<style type='text/css' media='screen' id='sm_css'> #smix {overflow: visible;height: auto;border-radius: 10px;max-width: 250px;background-color: #323232;text-align: left;font-size: 12px;line-height: 16px;font-family:'Lucida Sans Unicode','Lucida Grande',Verdana,Arial,Helvetica,sans-serif;-webkit-border-radius: 10px;-moz-border-radius: 10px;border-radius: 10px;} #smix a {color: #0056CC;text-decoration: none;} #smix .sm_head {color: #fff; line-height: 1em;font-size: 1.4em;padding: 10px;color: #fff;} #smix .sm_lanyard_wrapper {background-color: #fff;;clear: both;width: 97%;margin: 0 auto;margin-bottom: 0px;} #smix .sm_lanyard_content {padding: 7px;}#smix button.sm_rec, #smix a.sm_rec, #smix input[type=submit].sm_rec { padding: 6px 10px; -webkit-border-radius: 2px 2px;-moz-border-radius: 2px; border-radius: 2px; border: solid 1px rgb(153, 153, 153); background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(255, 255, 255)), to(rgb(221, 221, 221))); color: #333; text-decoration: none; cursor: pointer; display: inline-block; text-align: center; text-shadow: 0px 1px 1px rgba(255,255,255,1); line-height: 1; }#smix .sm_rec:hover { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(248, 248, 248)), to(rgb(221, 221, 221))); }#smix .sm_rec:active { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(204, 204, 204)), to(rgb(221, 221, 221))); }#smix .sm_rec.medium { padding: 3px 7px; font-size: 13px; }#smix .sm_rec span.icon.thumbs_up {background-position: 0px 36px;vertical-align: text-top;display: inline-block;margin-right: 4px;height: 18px;width: 16px;background-image: url(http://speakermix.com/images/new/thumbsold.png);}#smix .sm_rec:hover span.icon.thumbs_up {background-position: 0px 18px;} #smix .sm_events {padding:2px 0px 4px 0px;} #smix .sm_section {font-size: 10px; border-bottom: 1px solid silver; margin-bottom: 6px;} #smix .sm_subline {font-size:120%;margin-top:4px;font-weight:bold} #smix .powered {text-align: right} #smix .powered img {margin: 7px} </style>
Sela Technology Center

Advertisement

October 2008 - Posts

Serializing Expression Trees - MetaLinq V1.1

MetaLinq project now supports serializing expression trees with XmlSerializer.

For further information about this project, read my previous post on the subject.

Serializing Expression Trees - V1

I've blogged before (in hebrew) about the difficulty of serializing expression trees to XML.

To conclude my hebrew post, I've found a project in CodePlex, called MetaLinq which might be the solution to the problem - this open source allows to perform Linq queries over expression trees, and as a consequence, might allow serialization of the navigable expression tree.

I've worked in past few days to fix the code of the project to allow serializing the tree with DataContractSerializer.

The project can be downloaded from here.

The next version will :

  1. Support XML serialization with XmlSerializer
  2. Better documented code
  3. Extensive test project and samples
  4. Code improvements (thread safe, performance ...)

Comments are welcomed.

Enjoy.

Entity Framework generated queries - look out

One of the least explored field in Entity Framework is what happens to your queries when you work with a large set of entities and hierarchies.

When querying an entity that has a -to-many relations, the generated query is a simple query - contains only the fields of that entity.

When querying an entity that has a -to-1 relations (1:1, N:1, 1:0..1 ...), the generated query contains the fields of the queried entity and the keys of every -to-1 relations. This was made to allow the related entities to automatically be referenced to already loaded entities (in case the related entities were loaded before, they will be automatically referenced, without the need to reload data from the DB).

Note that this doesn't occur for -to-N relations (1:*, 0..1:*, *:*), probably because they tried to avoid selecting to many rows.

Another problem arises when the related entity is a base class to a hierarchy of entities - in this case, when the main entity is queried, the generated SQL will contain "left joins" for every derived type of the referenced entity and not only the referenced type (the base type) itself. When dealing with a large hierarchy, this can cause your queries to become very slow. For example, I had a model with 15 derived types, which caused querying a simple entity related to the base type to take over 1 minute to execute (querying 15 left joins).

If you encounter this problem, there is a simple solution that can be applied to some cases - if you only need that specific entity, with neither of the relations and you don't plan to change it further on, use the NoTracking enum of the MergeOption property (part of the ObjectQuery type). When the NoTracking options is set, the entity is loaded but isn't attached to the context, making the generated SQL contains only the fields of that entity without the keys of the related entities.

Sample model:

image

Generated SQL for loading a person object (Notice that the address table isn't queried):

SELECT 
[Limit1].[C1] AS [C1], 
[Limit1].[Id] AS [Id], 
[Limit1].[FirstName] AS [FirstName], 
[Limit1].[LastName] AS [LastName], 
[Limit1].[Age] AS [Age], 
[Limit1].[Id1] AS [Id1]
FROM ( SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[FirstName] AS [FirstName], 
    [Extent1].[LastName] AS [LastName], 
    [Extent1].[Age] AS [Age], 
    [Extent2].[Id] AS [Id1], 
    1 AS [C1]
    FROM  [dbo].[Person] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Cars] AS [Extent2] ON [Extent1].[Id] = [Extent2].[PersonId]
)  AS [Limit1]
 
 
Generated SQL after setting the MergeOption:
SELECT TOP (1) 
[c].[Id] AS [Id], 
[c].[FirstName] AS [FirstName], 
[c].[LastName] AS [LastName], 
[c].[Age] AS [Age]
FROM [dbo].[Person] AS [c]