Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Friday, January 31, 2014

LINQPad : debugging with Visual Studio

I've been a fan of LINQPad for a while and I use it a lot for writing code snippets and testing them.

Note: If you pay for it, you get Intellisense as well.

Came across a situation where I had a bug and couldn't put my finger on it. Would be ideal to debug / step-through it but you can't ...

Well, actually you can - learn something new every day.

Add these lines to your snippet:

Debugger.Launch();
Debugger.Break();

So obviously LINQPad is running
Start up Visual Studio - the normal Start screen is fine
Debug - Attach to Process
Select LINQPad.exe from the list and Attach
Run your snippet

BINGO - jumps into VS - debug away.

How have I not known about this?

Enjoy!

Wednesday, December 18, 2013

ADFS : Integrating with AuthorisationServer

Have been playing around with this and using ADFS as my IDP.

Good article on how to do this - Adding OAuth2 to ADFS (and thus bridging the gap between modern Applications and Enterprise Back ends).

But I battled with getting the admin stuff to work.

When you first configure it, it asks for an admin. name that is written to the SQL CE 4.0 DB.

Put some thought into this because this is an attribute that you have to provide in the form of a claim.

Assume my standard login name is jbloggs. So that's what I entered.

But when I configured ADFS, I mapped DisplayName to Name. But my DisplayName is "Joe" or "Joe Bloggs" or whatever.

So I ended up mapping my sAMAccountName (which is jbloggs) to Name and all was well.

Also, the DB is placed in the AppData folder and the file type is .sdf.

I found the easiest way to examine it was via LinqPad.

"Add Connection" / Next / Provider = CE SQL 4.0 / Browse to sdf file / OK.

Enjoy!

Friday, February 04, 2011

LINQ : LINQPad sample not a valid zip file

Under the Samples tab in LINQPad, you can download more samples.

When I clicked this, I got an error telling me that the file in ...\AppData\Local\Temp\LINQPad was not a valid zip file.

WTF?

So I ran up the estimable Fiddler in order to see what was happening and when I tried it, it all worked!

Somehow, putting Fiddler in the middle fixes the problem.

Bizarre, but alls well that ends well!

Enjoy!

Wednesday, November 19, 2008

LINQ : Simple LINQ to XML

It's really simple to construct XML documents with LINQ. This simple construct (inside LINQPad):


XDocument simpleDoc =
  new XDocument(
    new XElement("TopLevel",
      new XElement("SecondLevel",
        new XElement("a", "b",
        new XAttribute("class", "level"))
      )
    )
  );

simpleDoc.Dump();


produces:


<TopLevel>
  <SecondLevel>
    <a class="level">b</a>
  </SecondLevel>
</TopLevel>


Enjoy!

Tuesday, November 18, 2008

LINQ : LINQPad with auto-completion / Intellisense

This is in beta as we speak.

If you can't wait, invoke as:

LINQPad -beta

Really unlocks the power of LINQ since you can now see what options are available.

Enjoy!

LINQ : LINQ samples and ObjectDumper

There's a good selection of LINQ samples here. I ran up most of them in LINQPad.

However, some of these samples use a method called ObjectDumper (which does much the same job as object.Dump() in LINQPad).

The source for ObjectDumper can be found in this zip file. Save the files in an ObjectDumper directory somewhere and load them as a Project under Visual Studio. (Note that the sample is for VS 2008 but I had no problems doing this with VS 2005. Just remember to click on the .csproj to open the project and not the .sln!).

Then build the project which will create a .dll and add this .dll to the LINQPad "snippet" using "Advanced Properties" (F4)", then "Add" and then "Browse" to where you created the .dll.

Enjoy!

LINQ : Use of elements of string array

Again, using LINQPad:


string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

var getDigits =
from d in digits
where d[0] == 't'
select d;

getDigits.Dump();


This selects all elements in the array where the first letter is "t".

Result is:

two
three

Enjoy!

Wednesday, November 12, 2008

LINQ : ToArray() and Take()

Using the usual LINQPad and the Northwind DB:

So we first get the last names from the Employees table and put them into a string array using the ToArray() construct and then we get the first 4 using the Take() construct.


string [] allEmployees1 = Employees.Select (e => e.LastName).Take(4).ToArray();

allEmployees1.Dump();

foreach (string s in allEmployees1)
Console.WriteLine(s);


Enjoy!

LINQ : Some string handling

Based on an example by Eric White, here's some simple string handling (running as always inside LINQPad).


// Per Eric White. The following is a query to split a string into words, only
// allow words > 1 character, eliminate the ones that contain the letter
// "y", convert the words to lower case, count the number of occurrences of
// each word, and return the ten most used words.

string text = "Debugging LINQ queries can be problematic. One of the reasons is that quite often, you write a large query " +
"as a single expression, and you can’t set a breakpoint mid-expression. Is LINQ really that problematic? " +
"Queries can be fun as is debugging!";

var uniqueWords = text
.Split(' ', '.', ',', '?', '!')
.Where (i => i != "")
.Where (i => i.Count() > 1)
.Where (i => !i.Contains ("y"))
.Select(i => i.ToLower())
.GroupBy(i => i)
.OrderByDescending(i => i.Count())
.Select(i => new { Word = i.Key, Count = i.Count() })
.Take(10);

uniqueWords.Dump();


Returns:

Word Count
is 3
debugging 2
linq 2
queries 2
can 2
be 2
problematic 2
that 2
as 2
one 1

Enjoy!

Friday, November 07, 2008

LINQ : Some more on foreign keys

Continuing the series of LINQ to SQL using the Northwind DB:

Note: Can only be done if table has "Entity Set" relationship with another table i.e. green left-pointing arrow in LINQPad

Let's start with a compiled query:


var products = CompiledQuery.Compile ((TypedDataContext dc, decimal minUnitPrice) =>
from prod in Products
where prod.OrderDetails.Any (c => c.UnitPrice > minUnitPrice)
select prod
);

products (this, 20).Dump ("Unit price > $20");



OK - let's try that as a simple lambda without the compiled query:


var products1 =
from prod in Products
where prod.OrderDetails.Any (c => c.UnitPrice > 20)
select prod;

products1.Dump();


OK - let's try writing that again the "SQL" way with foreign key x = foreign key y:


var products2 =
(from prod in Products
from od in OrderDetails
where od.UnitPrice > 20 && prod.ProductID == od.ProductID
select prod).Distinct();

products2.Dump();


Hang on! There's far too many rows. That's because the relationship is duplicated so we need to add the "Distinct" keyword. You'd think that the construct would be:

select prod.Distinct();

but that doesn't work. If you look closely at the code snippet above, you'll see that the "Distinct" is applied to the whole clause (look at the brackets) rather than just the "Select" element.

Enjoy!

Thursday, November 06, 2008

LINQ : Compiled Queries

Continuing my playing with LINQPad, I found that you could put the query within a function that is precompiled (much like a stored procedure).

Using the Northwind DB,


var pp = CompiledQuery.Compile ((TypedDataContext dc, decimal minUnitPrice) =>
from p in Products
where p.UnitPrice > minUnitPrice
orderby p.UnitPrice
select p
);

pp (this, 10).Dump ("Products with unit price > 10");
pp (this, 100).Dump ("Products with unit price > 100");


This is equivalent to the "normal" form:


var pp1 =
from p in Products
where p.UnitPrice > 10
orderby p.UnitPrice
select p;

pp1.Dump();


Enjoy!

LINQ : Some sample queries

Been paying around with LINQ to SQL using the excellent LINQPad and the Northwind DB.

Some samples I came up with:

(The "C# Expression" refers to the Type in LINQPad. Ensure the DB drop-down points to the Northwind DB. The lambda is generated during run time and can be viewed by clicking on the lambda symbol next to the Results tab. You can think of lambda as a function e.g. "a => a * 2" is a function that takes "a" as input and returns "a times 2".

The Dump statement just outputs the current object.)



// This works - C# Expression
// Get all rows in Products - sort by ProductName

from p in Products
orderby p.ProductName
select p

// This is the corresponding lambda - C# Expression

Products
.OrderBy (p => p.ProductName)

// C# Expression
// Only show rows that have an "A" in the ProductName

from p in Products
where p.ProductName.Contains("A")
select p



These are all C# Statement(s) - ";" are now required at the end of declarations.



// Return all rows of employees who live in the UK sorted by LastName

var employees =
from emp in Employees
where emp.Country == "UK"
orderby emp.LastName
select emp;

employees.Dump();



Some more complicated ones.



// Find all products that are in stock

var products =
from prod in Products
where prod.UnitsInStock > 0
orderby prod.UnitsInStock
select prod;

products.Dump();

// And the lambda

Products
.Where (prod => ((prod.UnitsInStock) > 0))
.OrderBy (prod => prod.UnitsInStock);

Products.Dump();

// Putting the lambda on one line

Products.Where (prod => ((prod.UnitsInStock) > 0)).OrderBy (prod => prod.UnitsInStock);
Products.Dump();



What about two tables with a foreign key relationship? Let's throw in two "where" statements for fun!



// Find all products that are in stock and that whose category is Beverages

var products =
from prod in Products
from cat in Categories
where prod.UnitsInStock > 0 && prod.CategoryID == cat.CategoryID && cat.CategoryName == "Beverages"
orderby prod.UnitsInStock
select prod;

products.Dump();

// Write the rows out individually line-by-line

foreach(var prod in products)
Console.WriteLine(prod.ProductID + " " + prod.ProductName);

// "products" is an object which we can simply re-sort without another DB look-up

var products2 =
from prod in products
orderby prod.ProductID
select prod;

Console.WriteLine();

foreach(var prod in products2)
Console.WriteLine(prod.ProductID + " " + prod.ProductName);



Enjoy!