martedì, dicembre 20, 2011

How to mix entity framework and tsql commands

Entity Framewok is a powerful library. But sometimes you need to mix Entity Framework activities and standard TSQL command on the same connection and under the same transaction. The easiest way to do that is using a TransactionScope area:

using(TransactionScope ts = new TransactionScope())
{
  ...
  ... write your EF code and your TSQL code (sqlconenction + sqlcommand + ...)
  ...
  ts.complete();
}

TransactionScope works fine but in many cases the transaction is escalated to a distributed transaction so you need to setup the MSDTC and you lose in performance.

Using NET 4.0 there is a simple and very powerful solution: ObjectContext.ExecuteStoreCommand(string)
The method sends the command directly to the underlying database. It uses the same connection of the ObjectContext. But... it's not transactional with SaveChanges. :(
Solution: a couple of command to explicitely open connection and manage a global transaction.

var mydb = new MyEFDB();
mydb.Connection.Open();
var tran = mydb.Connection.BeginTransaction();
...
// (now you can mix you EF code with your TSQL code)
...
mydb.ExecuteStoreCommand("DELETE FROM MyTable WHERE ...");
...
foreach(var c in mydb.Customers)
  c.Name=....
...
mydb.SaveChanges();
tran.Commit();
mydb.Connection.Close();


Steps:

  • open the db connection
  • begina the transaction
  • do your TSQL and EF
  • save EF changes
  • commit transaction
  • close connection








martedì, novembre 01, 2011

Scuotere un LG Optimus One per installare il firmware

Domandona: come si fa a ripristinare il firmware originale su un LG Optimus One? Semplice, basta scuoterlo.
Beh, ok, non basta solo scuoterlo, ma fra le altre cose bisogna anche "shakerarlo" un po'. All'inizio non ci credevo ma visto che KDZ non riusciva a caricarmi il firmware, ci ho prova. E ha funzionato!!!
Qui c'è la procedura in italiano per ripristinare il firmware con il link ai vari firmware:
http://www.androidworld.it/forum/modding-e-firmware-lg-optimus-one-114/%5Bguida%5D-ripristino-firmware-ufficiale-tramite-kdz-10080/
Maggiori dettagli su Xda-Developers:  http://forum.xda-developers.com/showthread.php?t=883314

Per la cronaca: stavo facendo l'aggiornamento ufficale di LG e si è pianto tutto. Il telefono è rimasto in Emergency Mode e non c'è stato verso di farlo ripartire. Ovviamente non era neanche possibile ripartire con l'aggiornamento  :(
Prima di portarlo in assistenza ho provato la procedura con KDZ e ha funzionato (modalità EMERGENCY). Alla fine ho dovuto fare anche un hard reset (tasto home+volume_giù+power). Quindi telefono completamente "nuovo": rimesso il mio account gmail e in 5 minuti avevo nuovamente tutti i miei contatti, email e calendario. :)

domenica, settembre 18, 2011

How to get users list from Google Apps using OAuth and C#

Recently I've added support for Google Apps to GDocBackup. Using a domain administrator username+password it retrieves users list and then backups all documents for each user. The backup is executed using the OAuth domanin keys. So GDocBackup uses two different authentication method: username+password and OAuth.  I don't like that. I'd like to use OAuth for both tasks. After some tests, internet search and the help of Claudio Cherubino, I've done a working application.
This is a very quick step-by-step guide on how I used OAuth.

Step 1 : activate OAuth for your domain. Go to domain control panel -> Advanced tools -> Manage OAuth domain key and activate the key.


Step 2 : enable readonly Provisioning API.  Go to domain control panel -> Advanced tools -> Manage third party OAuth Client access.  Under [Client Name] add your full domain name. Under [One or more api scopes] add https://apps-apis.google.com/a/feeds/user/#readonly. Then press [Authorize].


Step 3 : download the official Google GData library for .NET: http://code.google.com/p/google-gdata/

Step 4 : create a C# application with Visual Studio, add the required DLL from Google GData library and write a piece of code like the following. It will retrieve all user login.



string mydomain = "___mydomain___";
string myOAuthConsumerSecret = "___mysecretkey___";


GOAuthRequestFactory reqF = new GOAuthRequestFactory("apps", "mytestapp");
reqF.ConsumerKey = mydomain;
reqF.ConsumerSecret = myOAuthConsumerSecret;


UserService userService = new UserService("mytestapp");
userService.RequestFactory = reqF;


UserQuery query = new UserQuery(mydomain, true);
UserFeed usersFeed = userService.Query(query);
foreach (UserEntry entry in usersFeed.Entries)
    Console.WriteLine(entry.Login.UserName);



[Update]
Details about API authorization: http://www.google.com/support/a/bin/answer.py?answer=162106



domenica, agosto 28, 2011

GDocBackup for Google Apps

Today I've published the first release of GDocBackup with support for Google Apps. It's a very preliminary release with some issues. It's very easy to use: in the config section, insert the administrator username and password, the domain name and the "OAuth consumer secret" key. Then activate "Google Apps mode" checkbox.  GDocBackup will extract all the documents for each user of your domain.

GDocBackup 0.4.40.153   http://code.google.com/p/gdocbackup/downloads/list



giovedì, maggio 19, 2011

How to intercept the sql query generated by an EntityDataSource

The asp.net EntityDataSource (= Entity Framework data source) hides SQL details. But sometimes you could need to see the auto generated SQL command.

Simple: intercept the QueryCreated event of the EntityDataSource

protected void EntityDataSource1_QueryCreated(object sender, QueryCreatedEventArgs e)
{
   LabelX.Text = (e.Query as System.Data.Objects.ObjectQuery).ToTraceString();
}




If are using an ObjectContext, you can extract the SQL casting the query to ObjectQuery.

var db = .... ObjectContext...
var query = (from x in TableName select x);
string sqlquery = (query as System.Data.Objects.ObjectQuery).ToTraceString();


venerdì, febbraio 25, 2011

ILSpy

Dalla fine di Febbraio 2011 Reflector non sarà più un prodotto gratuito. Due alternative: 35$ per la versione a pagamento oppure ILSpy.
ILSpy è disassemblatore come Reflector, è open-source ed è gratuito. Sviluppato dalle stesse persone di SharpDevelop.  L'ho provato e sembra funzionare molto bene. :)




[Update:  al momento non supporta LINQ. Forse in futuro... http://wiki.sharpdevelop.net/SharpZipLib_Roadmap.ashx]

mercoledì, febbraio 09, 2011

Piccolo contributo ad un libreria di Google

Vabbè, lo so è proprio una cosa da poco, sono solo 10 righe di codice o poco più, ma comunque la cosa mi fa proprio piacere.  Un grazie a Claudio.
http://code.google.com/p/google-gdata/issues/detail?id=477

domenica, febbraio 06, 2011

How to transform a pure Class Library project into a WCF Service Library

WCF Service Library projects are classic Class Library projects plus some very useful features:
  • they auto-host themselves using the utility WCF Service Host
  • they can be called and tested using the utility WCF Test Client
  • they can be discovered and added in other projects of the same solution using "Add Service Reference..."

(WCF Service Host and WCF Test Client are part of Visual Studio 2010).

The differences between the two type of project are in the .csprojct file. So, you can transform a classis Class Library project inot a WCF Service Library project modifying the .csproj file.

Steps:

* close VS2010
* do a complete backup of the whole solution   :)
* edit the "Class Library" .csproj using notepad (or other text editor)
* under <PropertyGroup> add:
    <ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <StartArguments>/client:"WcfTestClient.exe"</StartArguments>


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

    <ProjectExtensions>
    <VisualStudio>
    <FlavorProperties GUID="{3D9AD99F-2412-4246-B90B-4EAA41C64699}">
    <WcfProjectProperties>
    <AutoStart>True</AutoStart>
    </WcfProjectProperties>
    </FlavorProperties>
    </VisualStudio>
    </ProjectExtensions>



    The resulting file should looks like this:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{08536F3E-152A-46C0-8C63-C0821FE5DE7C}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>PureClassLib</RootNamespace>
    <AssemblyName>PureClassLib</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <StartArguments>/client:"WcfTestClient.exe"</StartArguments>

    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    </PropertyGroup>
    <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    </ItemGroup>
    <ItemGroup>
    <Compile Include="AcmeService.cs" />
    <Compile Include="Class1.cs" />
    <Compile Include="IAcmeService.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    </ItemGroup>
    <ItemGroup>
    <None Include="app.config" />
    </ItemGroup>
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    <ProjectExtensions>
    <VisualStudio>
    <FlavorProperties GUID="{3D9AD99F-2412-4246-B90B-4EAA41C64699}">
    <WcfProjectProperties>
    <AutoStart>True</AutoStart>
    </WcfProjectProperties>
    </FlavorProperties>
    </VisualStudio>
    </ProjectExtensions>

    <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
    Other similar extension points exist, see Microsoft.Common.targets.
    <Target Name="BeforeBuild">
    </Target>
    <Target Name="AfterBuild">
    </Target>
    -->
    </Project>




    A useful link to understand Project Types:  http://www.mztools.com/Articles/2008/MZ2008017.aspx



    Connet an Android app to Google App Engine - Authenticated !

    Sometime ago I read a very interesting post on Nick'blog: "Authenticating against App Engine from an Android app"  http://blog.notdot.net/2010/05/Authenticating-against-App-Engine-from-an-Android-app
    The code was very intersting but I need to refactor a bit and I'd like to add some "utility" method.
    Also I added a way to automatically invalidate old Auth token and get a new one.

    My code (very alpha... I'm still working on it...) is here:
    http://code.google.com/p/fhpublicstuff/source/browse/test/GAEConnector/GAEConnector.java

    [Update: it manages http and https connections to GAE]

    Usage:


    // ....
    _gaeConnector = new GAEConnector(null, "http://AAAAAAAA.appspot.com");
    if (!_gaeConnector.Authenticate(MyTest.this)) {
      message = "***AUTHENTICATION ERROR***";
    }
    // .....
    if (_gaeConnector.isAuthenticated()) {
      int httpStatusCode = _gaeConnector.GETContent("/myurl", true, true);
      if (httpStatusCode == 200) {
        String content = _gaeConnector.getLastContent();
        // ....