Dopo aver installato VS 2008 side by side con VS 2005 sulla stessa macchina ho trovato alcune incongruenze/cose da fare, e alcune differenze aggiuntive rispetto al post precedente "ASP.NET 3.5: insomma, quali sono le novità ? What's new".
ASP.NET System.DataSet.Extensions nella RTM è in versione 3.5.0.0, ma visto che non uso mai i DataSet non me ne ero accorto :-)
Windows Mobile 6.0 SDK
Visual Studio 2008 esce con il Windows Mobile 5.0 SDK a bordo. Occorre installare a mano, come abbiamo avuto modo di dire nei vari post da maggio a oggi, il nuovo Windows Mobile 6.0 SDK. Il problema è che l'SDK era già installato sulla mia macchina per lavorare con Visual Studio 2005. Ho provato a fare un Repair dell'installazione sperando che aggiornasse i riferimenti anche su Visual Studio 2008, ma niente da fare. L'unica soluzione che ho trovato è disinstallare e reinstallare il Windows Mobile 6.0 SDK (prendete le versioni Refresh uscite a maggio in occasione della MEDC se non l'avevate già) http://www.microsoft.com/downloads/details.aspx?familyid=06111a3a-a651-4745-88ef-3d48091a390b&displaylang=en.
Ecco lo screenshot delle due versioni di VS veramente side-by-side :-)
Qual'è il 2008 ?
SQLCE 3.5
L'installazione non comprende i server tools. Il readme indica come link al download gli strumenti di SQL 2005 Mobile Edition versione 3.0. vi consiglio di installare invece quelli della versione 3.1 usciti a gennaio 2007 dal link http://www.microsoft.com/downloads/details.aspx?FamilyId=4E45F676-E69A-4F7F-A016-C1585ACF4310&displaylang=en. Ho comunque fatto una prova agganciando entrambe le versioni server (3.0 e 3.1) dal client SQL CE 3.5 e funziona in entrambi i casi sia per RDA che per Merge Replication. Restiamo quindi in attesa di una nuova versione server a 64 bit visto che le versioni attuali ci costringono a far girare IIS a 32 bit anche su una macchina a 64 Bit.
L'help, da sempre download separato, è invece scaricabile da quì: http://www.microsoft.com/downloads/details.aspx?FamilyID=9ed47992-335d-4199-86cd-7b4f510e46da&displaylang=en. E' ancora allineato alla Beta2, ma non è cambiato praticamente niente nella RTM quindi è già utilizzabile in attesa del nuovo. Si può usare tranquillamente l'helper per la 3.1 visto che l'architettura e le metodologie di accesso non sono cambiate. L'help è sempre esterno a Visual Studio e utilizzabile tramite il file .CHM: si può integrare in Visual Studio Combined Help Collection seguendo questi passi:
-
Aprire l'Help di Visual Studio 2008
-
Andare su Help e poi Index
-
Nella finestrina indicare "collection manager" e poi cliccare Help sul collection manager nell'indice
-
Selezionare SQL Server Compact 3.5 e poi fare Update VSCC.
-
Ricordarsi di chiudere e riaprire l'help
Visual Studio 2008 torna ad installare SQLCE 3.5 sul device/emulatore collegato come faceva il suo nonno Visual Studio 2003 e addirittura il bisnonno Visual Studio 2002+SDE. Quindi per fare i test non è più necessario installare a mano SQLCE.
In pratica da un progetto che ha una reference a System.Data.SqlServerCe, Visual Sutdio installa
-
sqlce.ppc.platform.processor.cab: Componenti Core dell'engine
-
sqlce.repl.platform.processor.cab: Componenti per la replica RDA e Merge
-
sqlce.dev.processor.cab: ISQLW
System.Data.SqlClient
Ho trovato invece qualche problemino, che evidentemente deriva dall'installazione side-by-side dei due Visual Studio, sulla librerie per accedere direttamente a SQL Server. All'inizio pensavo fosse un problema di conversione dei progetti da VS 2005 a VS 2008, invece anche creando un nuovo progetto 2008 si presenta il problema.
In pratica con una reference alla System.Data.SqlClient (indicata in versione 3.0.3600.0, invece che 3.5 o al limite 2.0...già quì nasce qualche dubbio) Visual Studio cerca di fare il deploy di sql.ppc.platform.processor.cab prendendo quindi la vecchia versione 2.0 che chiaramente si schianta durante il setup sul device/emulatore in quanto manca il .NET Compact Framework 2.0: è un errore subdolo in quanto se il device o emulatore avessero il .NET CF 2.0 a bordo non ci accorgeremmo di niente.
Visual Studio 2005
Cosa sarà successo al buon vecchio Visual Studio 2005 ? Apparentemente niente, continua a funzionare: unico difetto il fatto che alcune librerie del .NET CF (come ad esempio la SqlClient e la SqlServerCe) si vedono doppie durante una Add Reference: occhio a prendere quelle giuste rispetto al .NET CF 2.0.
Device Emulator 3.0 e Tools
Visual Studio 2008, contrariamente alle previsioni, installa anche la versione 3.0 del Device Emulator. Vi ricordo che fino a questa versione gli emulatori non girano side-byside, ma una nuova versione "monta sopra" la versione precedente. Quindi anche VS 2005 si ritrova questa nuova versione. Per info sulle nuove caratteristiche vedere il mio articolo http://blogs.devleap.com/articolidevleap/archive/2007/11/17/visual-studio-2008-net-fw-amp-cf-3-5.aspx.
I Power Tools non sono ancora disponibili in versione finale. Ho provato a fare l'upgrade :-) dalla versione Beta2 alla versione RTM di un progetto in cui avevo usato il NETCFSvcUtil per creare un proxy verso un servizio WCF e il codice funziona, quindi non ci sono modifiche al codice generato lato client per la chiamata a servizi WCF.
Occhio ad una cosa che in realtà non ho poi approfondito. Facendo l'upgrade dei progetti dalla versione 2.0 alla versione 3.5 tramite il menù di Visual Studio 2008, vengono rieseguite le "Add Web Reference" verso i servizi rigenerando le classi proxu lato client: se, come nel mio caso, siete intervenuti nella classi generate (ad esempio per eliminare le classi rigenerate e utilizzare la vostra definizione (visto che lo /sharedtypes non si può fare dalle Web Reference)) vi ritrovate alla situazione di partenza. Motivo in più, come consiglia Paolo da sempre, per non fare Add Web Reference ma usare strumenti più evoluti come WSDL.exe per Web Service e SvcUtil.exe per WCF.
Ultima nota: la DataGrid non sta più dentro System.Windows.Forms.DataGrid.dll, ma ritorna, come tra l'altro era in .NET CF 1.0, dentro la System.Windows.Form: l'upgrade di un altro progetto aveva lasciato la reference e quindi la compilazione saltava in quanto non trovava la DLL corretta: è bastato rimuovere la reference a mano per ripristinare il tutto.
Andando a spasso su internet si trovano migliaia di post incrociati, rediretti e "rimbalzanti" l'uno con l'altro sulle novità del Framework 3.5. Quello che non ho trovato è un elenco dettagliato che vada oltre quanto già citato nell'ampia documentazione.
In questi giorni di raffreddore (per questo vado a spasso su internet e non nel bosco vicino casa mia :-)) ho messo mano ad un progetto ASP.NET 2.0 per vedere le reali implicazioni di migrazione verso la versione RTM ormai alle porte. Ovviamente il post non vuole essere completo di TUTTE le modifiche/novità.
Per prima cosa occorre mettere qualche puntino sulle "i". Spesso alcuni prodotti/tecnologie vengono indicate come novità della 3.5, mentre sono prodotti esistenti già in versione 2.0 o 3.0 che hanno ricevuto aggiunte/improvment nella 3.5
Non sono novità della 3.5:
1) Windows Workflow Foundation: già presente nella versione 3.0. Il prodotto/tecnologie esiste già da un anno (e personalmente lo trovo eccezionale !!!).
Ci sono alcune aggiunte come WorkflowRuntimeBehavior (e classi correlate) per ospitare workflow in WCF. La versione delle lilbrerie (almeno fino ad adesso) core di WF restano quindi in versione 3.0 e ad essa si aggiunge la System.WorkflowService in versione 3.5
2) Windows Presentation Foundation: già presente nella versione 3.0. Il prodotto/tecnologie esiste già da un anno. Non sono io la persona di riferimento (è Luca Regnicoli che si occupa di WPF nel nostro gruppo), quindi aggiungo solo che le varie dll restano in versione 3.0 tranne la System.Windows.Presentation
3) Windows Communication Foundation: già presente nella versione 3.0. Paolo nel suo blog ha già introdotto le novità
4) Windows CardSpace: già presente nella versione 3.0 e poco citato nei vari post/forum sulla versione 3.5
5) ASP.NET AJAX: già presente da circa 1 anno come libreria aggiuntiva System.Web.Extension in versione 1.0.61025.0 e come Add-in per Visual Studio 2005. Ci sono alcune novità di cui parliamo più avanti e non solo per AJAX all'interno della versione 3.5 di questa libreria.
La precisazione era dovuta solo per fare chiarezza e soprattutto per trovare meglio documentazione sui prodotti.
Vendiamo alle Novità di ASP.NET 3.5
Portando un progetto AJAX sotto Visual Studio 2008 il Conversion Wizard esegue alcune modifiche web.config. Innanzi tutto viene richiesto se portare il progetto alla versione 3.5 e, ovviamente rispondendo "Yes" troviamo queste aggiunte:
<system.web>
<compilation debug="false">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.DataSetExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
Vengono quindi aggiunte alcune delle librerie comuni della versione 3.5. In un web.config di una applicazione ASP.NET AJAX 1.0 veniva solo aggiunta la System.Web.Extension nella versione indicata prima.
Sempre nella sezione <system.web> vengono aggiunti/modificati
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>
La prima riga era presente anche nei progetti ASP.NET AJAX 1.0 (con la versione 1.0.61025.0) e consente di utilizzare il namespace asp: per i 4 controlli AJAX (ScriptManager, Timer, UpdatePanel, UpdateProgress) e le interfacce IScriptControl e IExtenderControl, nonchè il controllo base ExtenderControl.
La seconda riga, strana a prima vista, aggiunge il prefisso asp anche per i controlli presenti sotto System.Web.UI.WebControls della System.Web.Extensions.dll: i nuovi controlli ASP.NET sono stati inseriti in questa librerie e non nella classica System.Web.dll.
Nella sezione <system.codedom> viene invece configurato il compilatore C# 3.5 (o VB nel caso di progetti VB):
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" compilerOptions="/warnaserror-" warningLevel="4"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
</compiler>
</compilers>
</system.codedom>
come si nota providerOption viene impostato alla 3.5. Occorre ricordarsi ovviamente di verificare che in IIS l'applicazione sia associata a ASP.NET versione ?....2.0 ! Già, perchè, contrariamente a quanto si pensa (almeno fino alla RC di .NET FW 3.5) il motore di ASP.NET resta alla versione 2.0, potendo però usare i compilatori della 3.5 e le librerie della 3.5. L'architettura di ASP.NET, sin dalla versione 1.0, consente aggiunte di questo tipo. Quindi l'aggancio fra IIS e ASP.NET viene sempre fatto per le varie estensioni a c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll.
La sezione <configSections> resta praticamente inalterata. Questa la versione con ASP.NET AJAX 1.0:
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
Questa la versione della versione 3.5:
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/></sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
Quesito da Settimana Egninistica: trovate le differenze :-)
L'unica differenza, a parte la già citata versione della System.Web.Extensions è rappresentata dall'aggiunta del roleService: in pratica nella nuova versione viene esposto anche RoleManager (oltre a autenticazione e Profile già presenti nella precedente versione) alla libreria client di AJAX; si può interrogare anche l'appartenza a ruoli con una richiesta tramite i proxy lato client.
Anche le sezioni <httpHandler> e <httpModules> si aggiornano alla nuova versione della dll.
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
Così come la sezione <handler> e <module>, già prevista nella versione 1.0 di ASP.NET AJAX per l'integrazione della pipeline con IIS7:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</handlers>
</system.webServer>
A proposito di interazione/integrazione con IIS ricordo due cose:
1) Occhio al validateIntegratedModeConfiguration="false": questo flag indica a IIS 7 di non eseguire un controllo sulla configurazione di ASP.NET (già dalla versione 2.0) prima di eseguire l'applicazione in modalità integrata. In questo modo, giustamente, vengono saltati i controlli visto che il web.config AJAX è corretto per girare in IIS. Occhio solamente alle altre parti di configurazione custom che inseriamo nel config.
2) Contrariamente a quanto ho letto spesso su vari blog italiani e non, NON E' una novità della versione 3.5 l'integrazione con la Pipeline di IIS. Tale integrazione è già garantita dalla versione 2.0 (tanto è vero che anche il runtime della 3.5 è quello della 2.0) e quindi è possibile proteggere risorse non ASP.NET (.asp, .php, .jsp o semplici immagini) con i meccanismi di autenticazione di ASP.NET: in pratica se l'applicazione ASP.NET viene fatta girare in IIS7 in un Application Pool marcato come "integrated" viene eseguite SEMPRE la pipeline di ASP.NET anche per risorse non ASP.NET.
Ricordo anche con IIS6 e ASP.NET 2.0 è possibile proteggere risorse non ASP.NET con i meccanismi di autenticazione e autorizzazione di ASP.NET 2.0: è sufficiente indicare nel Wildcard Mapping di IIS la solita dll ISAPI (ASPNET_ISAPI.dll) per eseguire la pipeline di ASP.NET 2.0 per poi far recuperare la risorsa da IIS: questa coppia di versioni (IIS6 e ASP.NET 2.0) è la prima che consente di proteggere anche contenuti dinamici (.asp, .php, .jsp etc) con l'autenticazione/autorizzazione di ASP.NET. Il meccanismo sfrutta una funzionalità "vecchia" di IIS che usa una estensione denominata HSE_REQ_EXEC_URL che passa la palla a ASP.NET per l'esecuzione della pipeline; ASP.NET usa il DefaultHttpHandler che non fa nient'altro che ripassare la richiesta a IIS: se la risposta dell'autenticazione è positiva IIS processa la richiesta cercando, come se niente fosse successo, l'etensione ISAPI per eseguire la risorsa.
Per la precisione anche con ASP.NET 1.0 e IIS5 è possibile proteggere risorse, in questo caso però NON dinamiche (.gif, .jpg, .doc etc) tramite l'autenticazione di ASP.NET: in questo caso sarà lo StaticFileHandler di ASP.NET a prelevare la risorsa e per questo motivo non possono essere eseguite risorse dinamiche.
Questa filippica per sottilineare che ASP.NET 3.5 e IIS 7 non abbiano introdotto questa caratteristica: già le versioni precedenti erano dotate di questa interessante possibilità.
Visual Studio 2008 fornisce template per la creazione di AJAX Client Behavior, AJAX Client Library, AJAX Master Page, AJAX Web Form e AJAX WCF Service. Molte di queste cose si dovevano scrivere a mano: la nuova versione facilita il compito e standardizza un minino il modo con cui creare i sorgenti.
I nuovi controlli, che come abbiamo detto stanno sotto System.Web.Extensions, lasciando intatta e alla versione 2.0 la System.Web, sono
ListView
DataPager
LinqDataSource - vi rimando al libro Introducing Linq per una introduzione a LINQ. Il primo capitolo è disponibile sul sito ufficiale www.introducinglinq.com
Vi rimando alla documentazione su MSDN, più che esauriente su questi controlli.
E' disponibile uno strumento denominato aspnet_merge.exe che consente di unire assembly precompilati (tramite il noto aspnet_compiler della versione 2.0) per facilitare soprattutto l'aggiornamento di parti di codice dell'applicazione.
Ero curioso di vedere come LINQ risolvesse la paginazione su SQLCE 3.5 visto che adesso il provider funziona abbastanza bene.
A fronte di questa query lanciata da un metodo del Data Access Layer della nostra "ormai famosa" applicazione EstatesManagement che per semplicità e debug stampa sulla console i record estratti.
public void List(String idEstateType, Int32 pageSize, Int32 currentPage)
{
DataModelSQLCE.Estatesmanagement dc = new DataModelSQLCE.Estatesmanagement(ConfigurationManager.ConnectionStrings["DevLeap_EstatesManagement_DB_SQLCEConnectionString"].ConnectionString);
dc.Log = Console.Out;
var estates = (from c in dc.TabEstates
where c.IdEstateType == idEstateType
select c).Skip((currentPage - 1) * pageSize).Take(pageSize);
foreach (DataModelSQLCE.TabEstates estate in estates)
{
Console.WriteLine(estate.EstateDescription);
}
}
impostando pageSize a 4 e currentPage a 6 il risultato è il seguente:
SELECT TOP (4) [t0].[idEstate] AS [IdEstate], [t0].[idSalesman] AS [IdSalesman],
[t0].[idEstateType] AS [IdEstateType], [t0].[EstateDescription], [t0].[EstateAd
dress], [t0].[EstateEuroPrice], [t0].[EstateNotes], [t0].[EstateSold], [t0].[Est
ateImage], [t0].[EstateMetadata], [t0].[EstateGPSCoordinate], [t0].[rowguid] AS
[Rowguid]
FROM [tabEstates] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT TOP (20) [t1].[idEstate] AS [IdEstate]
FROM [tabEstates] AS [t1]
WHERE [t1].[idEstateType] = @p0
) AS [t2]
WHERE [t0].[idEstate] = [t2].[IdEstate]
))) AND ([t0].[idEstateType] = @p0)
-- @p0: Input String (Size = 0; Prec = 0; Scale = 0) [AAAAAAAAAAAAAAAAA]
-- Context: SqlProvider(SqlCE) Model: AttributedMetaModel Build: 3.5.20706.1
Impostando nella query una orderby sul prezzo
public void List(String idEstateType, Int32 pageSize, Int32 currentPage)
{
DataModelSQLCE.Estatesmanagement dc = new DataModelSQLCE.Estatesmanagement(ConfigurationManager.ConnectionStrings["DevLeap_EstatesManagement_DB_SQLCEConnectionString"].ConnectionString);
dc.Log = Console.Out;
var estates = (from c in dc.TabEstates
where c.IdEstateType == idEstateType
orderby c.EstateEuroPrice
select c).Skip((currentPage - 1) * pageSize).Take(pageSize);
foreach (DataModelSQLCE.TabEstates estate in estates)
{
Console.WriteLine(estate.EstateDescription);
}
}
il risultato è il seguente:
SELECT TOP (4) [t0].[idEstate] AS [IdEstate], [t0].[idSalesman] AS [IdSalesman],
[t0].[idEstateType] AS [IdEstateType], [t0].[EstateDescription], [t0].[EstateAd
dress], [t0].[EstateEuroPrice], [t0].[EstateNotes], [t0].[EstateSold], [t0].[Est
ateImage], [t0].[EstateMetadata], [t0].[EstateGPSCoordinate], [t0].[rowguid] AS
[Rowguid]
FROM [tabEstates] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT TOP (20) [t1].[idEstate] AS [IdEstate]
FROM [tabEstates] AS [t1]
WHERE [t1].[idEstateType] = @p0
ORDER BY [t1].[EstateEuroPrice]
) AS [t2]
WHERE [t0].[idEstate] = [t2].[IdEstate]
))) AND ([t0].[idEstateType] = @p0)
ORDER BY [t0].[EstateEuroPrice]
-- @p0: Input String (Size = 0; Prec = 0; Scale = 0) [AAAAAAAAAAAAAAAAA]
-- Context: SqlProvider(SqlCE) Model: AttributedMetaModel Build: 3.5.20706.1
peccato che le funzionalità di LINQ to SQL(CE) siano disponibili solo sul :NET Framework completo e non sul .NET CF e quindi ne relegano l'utilizzo agli scenari desktop e tablet.
UPDATED: Marco ha scritto qualche considerazione sul criterio e sui tipi di query: http://blogs.devleap.com/marco/archive/2007/11/26/paginazione-in-linq-to-sql.aspx