William さんのプロフィール.Net Zoneブログリスト ツール ヘルプ
1月9日

Enterprise Framework LINQ Queries failing - MSDN Forums

Good Linq post from Colin Meek below:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2078990&SiteID=1 

To give a sense of what is shared and what isn’t between LINQ to SQL and LINQ to Entities (both in terms of modules and behavior) I’ll repeat some information that’s probably familiar to most people on this thread…

LINQ providers support integrated query via the IQueryable and IQueryProvider interfaces. The provider’s job is basically to translate LINQ expression trees into native queries. LINQ to SQL and LINQ to Entities accomplish this translation in roughly the same way, though nothing is shared beyond the System.Linq components in System.Core.dll.

Matt Warren’s IQueryable series gives a more detailed overview (http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx) but I’ll include the highlights here to provide some context:

1. At compile time, user code is translated into (or directly uses) expression builder calls.

2. At runtime, calls to System.Linq.Queryable methods yield additional expression trees with argument expressions inline.

3. The provider is passed a LINQ expression which it translates into a “query” expression. LINQ to SQL and LINQ to Entities use different internal representations of the expression (a variant of LINQ expressions and Canonical Query Trees respectively). This step includes the replacement of method calls with query operators and the replacement of member accesses with store function calls.

4. Each provider then compensates for non-relational structures in the query (e.g. types, nested collections in results, etc.)

5. Native queries are generated and executed.

6. Query results are reshaped (basically the inverse of step 4).

As I mentioned, there is really nothing shared between LINQ to SQL and LINQ to Entities beyond step 2. The example in this thread illustrates a couple of differences between the two stacks in the handling of step 3 and step 4.

Implicit vs. explicit client evaluation

LINQ to SQL is a hybrid provider in the sense that it supports evaluation of parts of the query in the client and parts in the store. As a result, the following query succeeds in LINQ to SQL but fails in LINQ to Entities:

var query = from o in context.Orders

where GetCutoffDate() > o.OrderDate

select o;

As Brian suggested, it must be rewritten as:

DateTime cutoffDate = GetCutoffDate();

var query = from o in context.Orders

where cutoffDate > o.OrderDate

select o;

This makes the boundary between client and store evaluation explicit. There is a tradeoff between self-containment of queries and predictability of behavior for non-expert users.

Canonical functions vs. store functions

Of course, the sub-expression mentioned in this thread could be entirely translated into Transact-SQL function calls:

DateTime.UtcNow.AddDays(-180)

becomes

DATEADD(day, -180, GETUTCDATE())

Note that although LINQ to SQL could translate the above expression into Transact-SQL, it chooses to evaluate it on the client because it is uncorrelated. The behavior is different depending on whether results are correlated or not.

In Beta 2, LINQ to Entities does not support the DateTime.AddDays method simply because a corresponding “canonical function” does not exist. Canonical functions are store agnostic and can be implemented by arbitrary Entity Frameworks providers. We plan on introducing a few more DateTime-related functions in the next release (the usual disclaimers apply) at which point this expression will be supported by LINQ to Entities.

Regarding Rick’s question: Entity-SQL supports both canonical and store-specific functions. For functions not supported by LINQ to Entities, this provides the cleanest workaround. Where the gap is due to unsupported CLR methods – in either LINQ to SQL or LINQ to Entities – consider explicitly breaking up the query into client- and store- side elements. For instance, to extend the above example:

DateTime cutoffDate = GetCutoffDate();

var query = from o in context.Orders

where cutoffDate > o.OrderDate

select o;

var hybridQuery = from row in query.AsEnumerable()

select ShapeResult(row.Oid, row.Description, row.OrderDate);

Recommendation:

When working with LINQ to Entities, keep in mind that boundaries between client- and store- execution are explicit. To use a value computed on the client within a query, assign the value to a local variable before executing (see the assignment to cutoffDate above). To perform client-side processing of results, use the AsEnumerable method to yield results from the store query and then apply client-side logic (see the assignment to hybridQuery above).

Thanks,
-Colin

Enterprise Framework LINQ Queries failing - MSDN Forums

1月6日

Make existing project a Volta project - MSDN Forums

 

Yes, this is possible, allthough you will need to modify the project file by hand. You can do this by right-clicking on the project and selecting'Unload project'. Next you will need to right-click on it again and select 'Edit ???.??proj'.

Then in the top-level propertygroup add the VoltaProjectKind, VoltaVersion and the ProjectTypeGuids elements.

Code Block

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
     (....)

<VoltaProjectKind>WinformsApplication</VoltaProjectKind>

<VoltaVersion>1.0</VoltaVersion>

<ProjectTypeGuids></ProjectTypeGuids>

    (....)

</ProjectTypeGuids>

If it is a C# project insert:

{41daf090-9073-464d-9898-7bcdfc7d2642};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}

into the ProjectTypeGuids element. If it is a VB project insert:

{41daf090-9073-464d-9898-7bcdfc7d2642};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}

The last thing to do is to replace:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

or:

<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />

with:

<Import Project="$(VoltaInstallPath)\Microsoft.Volta.targets" />

This should do the trick. Please let us know if it doesn't.

Thanks,

Danny

Make existing project a Volta project - MSDN Forums