LitwareHR Sample Application May 2008 Just Released

May 7th, 2008 by pdamiani

Microsoft Architecture Strategy Team has just shipped a new version of their LitwareHR Sample Application. I’m proud to say that I was part of the team who helped them to achieve this amazing milestone :)

 litware1

Among other things, this release includes:

 litwareV3.features

You can download the sample application from Codeplex using this link.

Eugenio Pace has also published a series of posts where describes the "behind the scenes" behavior of the sample application, including code, screenshots, and a end to end demo video.

  1. SQL Server Data Services - SSDS - New version of LitwareHR
  2. LitwareHR on SSDS - Part I - Multi-tenancy & Flexibility
  3. LitwareHR on SSDS - Part II - The data access layer
  4. LitwareHR on SSDS - Part III - Data access enhancements 1: caching
  5. LitwareHR on SSDS - Part IV - Data access enhancements 2: developing offline
  6. LitwareHR on SSDS - Part V - Searching across Containers
  7. More on parallel queries across containers in SSDS
  8. LitwareHR on SSDS - Part VI - Unit of Work support
  9. Paging in SSDS & Parallel Queries
  10. End to end demo of LitwareHR on SSDS

Also you can find more information in this post by Gianpaolo Carraro.
Stay tuned to Gianpaolo’s and Eugenio’s blog for more information.

Thanks,
Lito

Posted in Uncategorized | 2 Comments »

How to change NetworkService Account proxy settings

November 25th, 2007 by pdamiani

If you need to change the proxy settings for the any of the system account like Network Service you can use the “bitsAdmin” command as shown in the following example:

bitsAdmin /Util /SetIEProxy NETWORKSERVICE MANUAL_PROXY [myProxy]:[myPort]

You can find the complete reference for this command at: http://msdn2.microsoft.com/en-US/library/aa362813.aspx

Thanks,

Lito

Posted in Uncategorized | No Comments »

ClickOnce blank page issue under IE7

November 22nd, 2007 by pdamiani

Last week I faced an issue when trying to download a clickOnce application using IE7. After browsing the download link, IE did nothing but showed a blank page, or actually it got closed.

Finally, I realized that this was caused because some security settings where missing. In order to workaround this, use the following steps:

1. Open IE
2. Go to Tools -> Internet options
3. Security Tab –> Click “Custom Level…” button for the Internet Zone

ClickOnce.IE7.SecuritySettings.1

4. Enable .Net Framework-reliant components as depicted below:

ClickOnce.IE7.SecuritySettings.2

Hope this helps.

Thanks,
Lito

Posted in Uncategorized | No Comments »

LitwareHR Sample Application November 2007 Just Released

November 22nd, 2007 by pdamiani

Microsoft Architecture Strategy Team has just shipped a new version of their LitwareHR Sample Application. I’m proud to say that I was part of the team who helped them to achieve this amazing milestone :)

litware2007-1

Among other things, this release includes:

  • Upgraded platform to VS 2008 Beta 2 and Windows Server 2008 RC0
  • Upgraded codebase
  • Simple RSS support
  • Simple REST interfaces
  • Enhanced data access for increased performance
  • Integration with Silverlight Streaming for "Video Resumes" feature
  • A new version of the Smart Client & integrated ClickOnce deployment

litwareV3.features

You can download the sample application from Codeplex using this link.

Also you can find more information in this post by Gianpaolo Carraro.
Stay tuned to Gianpaolo’s and Eugenio’s blog for more information.

Thanks,
Lito

Posted in Uncategorized | No Comments »

Installing ADAM on Windows Longhorn

October 13th, 2007 by pdamiani

When trying to install ADAM on Windows Server 2008 RC0 (aka Longhorn) Enterprise Edition, Build 6001, I faced the following error:

adamError

After doing some research, and playing around with the installation, I found the following workaround:

1.       Install ADAM on a non-Longhorn machine such as Windows Server 2003.

2.       Copy the %WINDIR%\ADAM folder that is created to the same location on your Longhorn  server

3.       Create a new registry key called HKLM\Software\Microsoft\Windows\CurrentVersion\ADAM_Shared

4.       Under this key, create a new Multi-String value called "SharedFolders"

5.       Copy the vssapi.dll file, located at %WINDIR%\System32 from the W2K3 installation, to the following destination in the Longhorn server: %WINDIR%\ADAM

6.       Now, run adaminstall.exe from your %WINDIR%\ADAM directory and follow the wizard.  Do not import any LDIF files.

7.       Finally, run ldifde.exe for each import you wanted to have in step #6.  The correct command line arguments to use are listed at the top of each .ldf file. Some examples:

%WINDIR%\adam\ldifde -i -f %WINDIR%\adam\MS-AZMan.ldf -s servername:port -k -j . -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext

%WINDIR%\adam\ldifde -i -f %WINDIR%\adam\MS-User.ldf -s servername:port  -k -j . -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext

%WINDIR%\adam\ldifde -i -f %WINDIR%\adam\MS-UserProxy.ldf -s servername:port  -k -j . -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext

%WINDIR%\adam\ldifde -i -f %WINDIR%\adam\MS-InetOrgPerson.ldf -s servername:port -k -j . -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext

8.       In order to enable the MMC “ADAM ADSI Edit” snap-in , register manually the following DLL using this command:

%WINDIR%\ADAM\regsvr32  -i  ADAM-ADSIEdit.dll

9.       Finally, add a shortcut to the MMC snap-in located at:

%WINDIR%\ADAM\ ADAM-adsiedit.msc

                        

References:       http://dunnry.com/blog/InstallingADAMOnVista.aspx

Hope this helps!

Posted in Uncategorized | 3 Comments »

Windows PowerShell Scripts Execution Policy

January 2nd, 2007 by pdamiani

Yesterday I’ve been playing around with the new Windows Powershell. As the name implies, this is the new shell for Microsoft Windows, a real shell compared to Cmd.exe.

One important topic about Windows Powershell is security. The primary security feature in Windows PowerShell is its execution policy. By default, this policy is set to Restricted, which you can verify by running the Get-ExecutionPolicy command-let. In Restricted mode, scripts don't run.

In order to run scripts, you should change the default execution policy mode using the Set-ExecutionPolicy command-let. This is a list of all available modes:

·         Restricted: In this mode scripts don't run.

·         RemoteSigned: This allows local scripts to run without being digitally signed. Remote scripts won’t run unless they've been digitally signed.

·         AllSigned: This mode doesn't allow any scripts to run unless they've been digitally signed.

·         Unrestricted: In this mode every script is allowed to run. 

I recommend setting the mode to RemoteSigned. This mode allows local scripts to run without being digitally signed, providing the easiest way to develop and test scripts: 

PS C:\> Set-ExecutionPolicy RemoteSigned 

For further information about Windows Powershell you could check this great introductory article!

Posted in Uncategorized | No Comments »

Understanding ASP .NET Impersonation

December 24th, 2006 by pdamiani

Impersonation is a process in which a user accesses the resources by using the identity of another user. With impersonation we can control the identity under which code is executed.

By default, ASP.NET does not use impersonation. When using impersonation, ASP.NET applications can execute the processing thread using the identity of the client on whose behalf they are operating. If impersonation is enabled for a given application, ASP.NET impersonates the access token that IIS provides to ISAPI extensions. That token can be either an authenticated user token, or the token for the anonymous user (such as IUSR_MACHINENAME) depending on the authentication mode.

Only application code is impersonated; compilation and configuration are read as the process token.

Impersonation for ASP.NET applications can be set up by using the tag in the Web.config file. We can specify impersonation in the following three ways:

  • This means impersonation is not enabled. 
  • This means impersonation is enabled.
  • This means impersonation is enabled, but the worker thread will run under the identity that will be generated by using the credentials specified.

The following table summarizes the identity used for code execution when using different authentication modes with impersonation enabled or disabled:

Authentication Mode

Impersonation

Content Access

Execution

Anonymous Access or Integrated Authentication

impersonate=false

Impersonated User from IIS

Application Pool Identity

Anonymous Access

impersonate=true

Impersonated User from IIS

Impersonated User from IIS:  IUSR_machinename

Integrated Authentication

impersonate=true

Impersonated User from IIS

Impersonated User from IIS: [authenticated user]

Anonymous Access or Integrated Authentication

impersonate=true userName=[user]

Impersonated User from IIS and user

[user]

References:

Posted in Uncategorized | No Comments »

New Features in C# 3.0

December 24th, 2006 by pdamiani

If you are interested in C# 3.0, there is an article at MSDN that details all the C# 3.0 Specification, with technical info and inline samples. You can find that article here!

Yesterday, while I was reading the article, I copied and pasted what I think summarizes best what’s new in the language, a sort of a quick reference for the new C# 3.0 features. Here is the result: 

Quick Reference for the new features in C# 3.0 (taken from the C# 3.0 Specification)

1. Implicitly Typed Local Variables

In an implicitly typed local variable declaration, the type of the local variable being declared is inferred from the expression used to initialize the variable:

var i = 5; 

var s = “Hello”; 

var d = 1.0; 

var numbers = new int[] {1, 2, 3}; 

var orders = new Dictionary<int,Order>();

Is equivalent to:

int i = 5; 

string s = “Hello”; 

double d = 1.0; 

int[] numbers = new int[] {1, 2, 3}; 

Dictionary<int,Order> orders = new Dictionary<int,Order>();

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2. Extension Methods

Extension methods are static methods that can be invoked using instance method syntax. In effect, extension methods make it possible to extend existing types and constructed types with additional methods.

Extension methods are declared by specifying the keyword this as a modifier on the first parameter of the methods. Extension methods can only be declared in static classes.

namespace Acme.Utilities
{

public static class Extensions
{
public static int ToInt32(this string s) {

return Int32.Parse(s);

}

public static T[] Slice<T>(this T[] source, int index, int count) {

if (index < 0 || count < 0 || source.Length – index < count)

throw new ArgumentException();

T[] result = new T[count];

Array.Copy(source, index, result, 0, count);

return result;

}

}

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Extension methods have all the capabilities of regular static methods. In addition, once imported, extension methods can be invoked using instance method syntax. Extension methods are imported through using-namespace-directives. In effect, imported extension methods appear as additional methods on the types that are given by their first parameter and have lower precedence than regular instance methods.

using Acme.Utilities; 

string s = “1234″; 

int i = s.ToInt32(); // Same as Extensions.ToInt32(s) 

int[] digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 

int[] a = digits.Slice(4, 3); // Same as Extensions.Slice(digits, 4, 3) 
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

3. Lambda Expressions

C# 2.0 introduces anonymous methods, which allow code blocks to be written “in-line” where delegate values are expected. Lambda expressions provide a more concise, functional syntax for writing anonymous methods.

A lambda expression is written as a parameter list, followed by the => token, followed by an expression or a statement block.

The parameters of a lambda expression can be explicitly or implicitly typed. In an explicitly typed parameter list, the type of each parameter is explicitly stated. In an implicitly typed parameter list, the types of the parameters are inferred from the context in which the lambda expression occurs-specifically, when the lambda expression is converted to a compatible delegate type, that delegate type provides the parameter types.

In a lambda expression with a single, implicitly typed parameter, the parentheses may be omitted from the parameter list. In other words, a lambda expression of the form

( param ) => exp.

can be abbreviated to

param => exp.

Some examples of lambda expressions follow below:

x => x + 1 // Implicitly typed, expression body

x => { return x + 1; } // Implicitly typed, statement body

(int x) => x + 1 // Explicitly typed, expression body

(int x) => { return x + 1; } // Explicitly typed, statement body

(x, y) => x * y // Multiple parameters

() => Console.WriteLine() // No parameters

A lambda-expression can be implicitly converted to a compatible delegate type.

The examples that follow use a generic delegate type Func<A,R> which represents a function taking an argument of type A and returning a value of type R:

delegate R Func<A,R>(A arg);

In the assignments

Func<int,int> f1 = x => x + 1; // Ok

Func<int,double> f2 = x => x + 1; // Ok

Func<double,int> f3 = x => x + 1; // Error: return type of double cannot be implicitly converted to int

When a generic method is called without specifying type arguments, a type inference process attempts to infer type arguments for the call. Lambda expressions passed as arguments to the generic method participate in this type inference process.

The following example demonstrates how lambda expression type inference allows type information to “flow” between arguments in a generic method invocation. Given the method

static Z F<X,Y,Z>(X value, Func<X,Y> f1, Func<Y,Z> f2)
{
    return f2(f1(value));
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

type inference for the invocation

double seconds = F(“1:15:30″, s => TimeSpan.Parse(s), t => t.TotalSeconds); 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

proceeds as follows: First, the argument “1:15:30″ is related to the value parameter, inferring X to be string. Then, the parameter of the first lambda expression, s, is given the inferred type string, and the expression TimeSpan.Parse(s) is related to the return type of f1, inferring Y to be System.TimeSpan. Finally, the parameter of the second lambda expression, t, is given the inferred type System.TimeSpan, and the expression t.TotalSeconds is related to the return type of f2, inferring Z to be double. Thus, the result of the invocation is of type double.

4. Object Initializers

An object initializer specifies values for one or more fields or properties of an object. An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas. Each member initializer must name an accessible field or property of the object being initialized, followed by an equals sign and an expression or an object or collection initializer.

The following class represents a point with two coordinates:

public class Point

{

int x, y;

public int X { get { return x; } set { x = value; } }

public int Y { get { return y; } set { y = value; } }

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

An instance of Point can be created and initialized as follows:

var a = new Point { X = 0, Y = 1 };

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Another sample:

public class Rectangle
{
  Point p1, p2;

  public Point P1 { get { return p1; } set { p1 = value; } }

  public Point P2 { get { return p2; } set { p2 = value; } }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

An instance of Rectangle can be created and initialized as follows:

var r = new Rectangle
{
  P1 = new Point { X = 0, Y = 1 },

  P2 = new Point { X = 2, Y = 3 }
};

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

5. Collection Initializers

A collection initializer specifies the elements of a collection. A collection initializer consists of a sequence of element initializers, enclosed by { and } tokens and separated by commas. Each element initializer specifies an element to be added to the collection object being initialized. To avoid ambiguity with member initializers, element initializers cannot be assignment expressions.

The following is an example of an object creation expression that includes a collection initializer:

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The collection object to which a collection initializer is applied must be of a type that implements System.Collections.Generic.ICollection<T> for exactly one T.

6. Anonymous Types

C# 3.0 permits the new operator to be used with an anonymous object initializer to create an object of an anonymous type. An anonymous object initializer declares an anonymous type and returns an instance of that type. An anonymous type is a nameless class type that inherits directly from object. The members of an anonymous type are a sequence of read/write properties inferred from the object initializer(s) used to create instances of the type. Specifically, an anonymous object initializer of the form

new { p1 = e1 , p2 = e2 , … pn = en } 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

declares an anonymous type of the form

class __Anonymous1

{

private T1 f1 ;

private T2 f2 ;

…

private Tn fn ;

public T1 p1 { get { return f1 ; } set { f1 = value ; } }

public T2 p2 { get { return f2 ; } set { f2 = value ; } }

…

public T1 p1 { get { return f1 ; } set { f1 = value ; } }

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In the example

var p1 = new { Name = “Lawnmower”, Price = 495.00 };

var p2 = new { Name = “Shovel”, Price = 26.95 };

p1 = p2;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

the assignment on the last line is permitted because p1 and p2 are of the same anonymous type.

7. Implicitly Typed Arrays

In an implicitly typed array creation expression, the type of the array instance is inferred from the elements specified in the array initializer. The following are examples of implicitly typed array creation expressions:

var a = new[] { 1, 10, 100, 1000 }; // int[]

var b = new[] { 1, 1.5, 2, 2.5 }; // double[]

var c = new[] { “hello”, null, “world” }; // string[]

var d = new[] { 1, “one“, 2, “two” }; // Error

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

8. Query Expressions

Query expressions provide a language integrated syntax for queries that is similar to relational and hierarchical query languages such as SQL and XQuery.

A query expression begins with a from clause and ends with either a select or group clause. The initial from clause can be followed by zero or more from or where clauses. Each from clause is a generator that introduces an iteration variable ranging over a sequence, and each where clause is a filter that excludes items from the result. The final select or group clause specifies the shape of the result in terms of the iteration variable(s). The select or group clause may be preceded by an orderby clause that specifies an ordering for the result. Finally, an into clause can be used to “splice” queries by treating the results of one query as a generator in a subsequent query.

The C# 3.0 language does not specify the exact execution semantics of query expressions. Rather, C# 3.0 translates query expressions into invocations of methods that adhere to the query expression pattern. Specifically, query expressions are translated into invocations of methods named Where, Select, SelectMany, OrderBy, OrderByDescending, ThenBy, ThenByDescending, and GroupBy that are expected to have particular signatures and result types. These methods can be instance methods of the object being queried or extension methods that are external to the object, and they implement the actual execution of the query.

· where clauses

A where clause in a query expression:

from c customers where c.City == “London” select c;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

translates to an invocation of a Where method with a synthesized lambda expression created by combining the iteration variable identifier and the expression of the where clause:

customers.Where(c => c.City == “London”)

· select clauses

A select clause that selects something other than the innermost iteration variable:

from c in customers where c.City == “London” select c.Name;

translates to an invocation of a Select method with a synthesized lambda expression:

customers.Where(c => c.City == “London”).Select(c => c.Name) 

· group clauses

A group clause:

from c in customers group c.Name by c.Country

translates to an invocation of a GroupBy method:

customers.GroupBy(c => c.Country, c => c.Name)

· orderby clauses

An orderby clause:

from c in customers orderby c.Name select new { c.Name, c.Phone }

translates to an invocation of an OrderBy method, or an OrderByDescending method if a descending direction was specified:

customers.OrderBy(c => c.Name).Select(c => new { c.Name, c.Phone })

Secondary orderings in an orderby clause:

from c in customers orderby c.Country, c.Balance descending select new { c.Name, c.Country, c.Balance }

translate to invocations of ThenBy and ThenByDescending methods:

customers.OrderBy(c => c.Country).ThenByDescending(c => c.Balance).Select(c => new { c.Name, c.Country, c.Balance })

· into clauses

An into clause:

from c in customers group c by c.Country into g select new { Country = g.Key, CustCount = g.Group.Count() }

is simply a more convenient notation for a nested query:

from g in from c in customers group c by c.Country select new { Country = g.Key, CustCount = g.Group.Count() }

the translation of which is:

customers.GroupBy(c => c.Country).Select(g => new { Country = g.Key, CustCount = g.Group.Count() })

The Query Expression Pattern

The Query Expression Pattern establishes a pattern of methods that types can implement to support query expressions. Because query expressions are translated to method invocations by means of a syntactic mapping, types have considerable flexibility in how they implement the query expression pattern.

The recommended shape of a generic type C<T> that supports the query expression pattern is shown below. A generic type is used in order to illustrate the proper relationships between parameter and result types, but it is possible to implement the pattern for non-generic types as well.

delegate R Func<A,R>(A arg);

class C<T>

{

public C<T> Where(Func<T,bool> predicate);

public C<S> Select<S>(Func<T,S> selector);

public C<S> SelectMany<S>(Func<T,C<S>> selector);

public O<T> OrderBy<K>(Func<T,K> keyExpr);

public O<T> OrderByDescending<K>(Func<T,K> keyExpr);

public C<G<K,T>> GroupBy<K>(Func<T,K> keyExpr);

public C<G<K,E>> GroupBy<K,E>(Func<T,K> keyExpr, Func<T,E> elemExpr);

}

class O<T> : C<T>

{

public O<T> ThenBy<K>(Func<T,K> keySelector);

public O<T> ThenByDescending<K>(Func<T,K> keySelector);

}

class G<K,T>

{

public K Key { get; }

public C<T> Group { get; }

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The methods above use a generic delegate type Func<A, R>, but they could equally well have used other delegate or expression tree types with the same relationships in parameter and result types.

Notice the recommended relationship between C<T> and O<T> which ensures that the ThenBy and ThenByDescending methods are available only on the result of an OrderBy or OrderByDescending. Also notice the recommended shape of the result of GroupBy, which is a sequence of groupings that each has a Key and Group property.

9. Expression Trees

Expression trees permit lambda expressions to be represented as data structures instead of executable code. A lambda expression that is convertible to a delegate type D is also convertible to an expression tree of type System.Query.Expression<D>. Whereas the conversion of a lambda expression to a delegate type causes executable code to be generated and referenced by a delegate, conversion to an expression tree type causes code that creates an expression tree instance to be emitted. Expression trees are efficient in-memory data representations of lambda expressions and make the structure of the expression transparent and explicit.

The following example represents a lambda expression both as executable code and as an expression tree. Because a conversion exists to Func<int,int>, a conversion also exists to Expression<Func<int,int>>.

Func<int,int> f = x => x + 1; // Code

Expression<Func<int,int>> e = x => x + 1; // Data

Following these assignments, the delegate f references a method that returns x + 1, and the expression tree e references a data structure that describes the expression x + 1.

For more information about C# 3.0 click here!

Posted in Uncategorized | No Comments »

Certified ScrumMaster training course in Argentina!

September 6th, 2006 by pdamiani

Hi everyone! It’s been a lot since my last post!


Today I want to share with you my experience about a training course I attended a month ago. I can say that I’m a “Certified ScrumMasternow, and I’m very proud!


The course was really excellent! I learnt a lot and settled concepts about Scrum. It was a pleasure to be part of it!


You could find information about this course here: CSM course


 


Here are some great posts from Tobias Mayer, our trainer during the course:



If you ever have a chance to attend a course like this, please don’t hesitate about it!

Posted in Uncategorized | No Comments »


RSS Subscribe to my feed

Recent Posts

Map

Categories

Archives

Tags

Recent Comments