Introduction

Introduction

 This is the first topic Next topic

Introduction

 This is the first topic Next topic

*** NOTE *** for X# and xBase guys :-

Many years after writing most of these eNotes I have returned to add suitable sections for xBase, and in

particular XSharp.

Since there is a HUGE amount of working code and examples in C#, I am leaving these intact and in place,

and just adding an Appendix called "Appendix X - full 'XSharp' syntax" in which I will provide all the necessary

syntax for code to use LINQ in both 'Simple Syntax' as well as 'Method and Lambda Syntax'.

It will also cover LINQ to Objects, LINQ to SQL, as well as LINQ to 'Entities'. .NET coder will need all three

of these if they are to embrace LINQ fully.

I strongly suggest that any reader new to LINQ takes the time to get familiar with the other topic sections

which were written for C#. These are easy enough to understand, before going to the relevant X# sections

for the correct syntax.

"You can't expect to move over into using LINQ in ten minutes !" You will need to spend some time and

quite a bit of effort - BUT - it is well worth it, I use nothing else these days.

Good Luck,

Phil.

=============================================================================

Hi guys, this is NOT going to be a set of eNotes which duplicates information from fine texts like those

of Pialorsi and Russo (see 'Books' subsection) or Fabrice Marguerie et al.

The point of my recorded notes in this eVolume is for me to get code working for me in the scenarios that

I need to handle.

This means that METRO and WPF are what I mainly need to cope with, as well as splitting things into both

in-memory objects - like Collections - and also ADO.NET stuff as I do lots of SQL back-end database work.

I usually like to work in Vulcan.net but until the features of LINQ are available there, I will use C# to explore

what we need to checkout about LINQ.

Anyway, we all need to have reasonable skills in C# (both reading and writing) if we are to survive in the .NET

universe, as the word 'world' is too small for .NET usage ;-)

Software Platform and Tools :

To follow through my exploration of LINQ I will use Windows 8, and Visual Studio 11 (2012) - this is beta at this

moment in time BUT the public release is due in four days time. This would suggest to me that I will be using

VS11 on Win8 very soon.

I will also try to NOT use any third party 'stuff' so that we can easily see just what is possible with LINQ and .NET

as the standard Microsoft products come 'out of the box'.

METRO and WPF :

Don't you panic about my use of METRO, if you do not have Windows 8. Since METRO style is GUI oriented, and

the LINQ technology is basically 'data centric', then what we do in METRO we should also be able to do in WPF.

It just happens that my exploration of LINQ comes at a time when I am part way through learning METRO and

writing 'ClickStart' eNotes on 'Metro' style app creation.

As more modern technologies are released by Microsoft we will see then favouring the use of LINQ, just as I found

out the other day when I wished to sort and filter a 'View' of a Collection in METRO. It was not possible to do it the

old WPF way.

This is what 'Scott Guthrie' has to say :-

PHH - 11th. August 2012.


Hardware Platform used for eNotes

Hardware Platform used for eNotes

 Previous topic Next topic

Hardware Platform used for eNotes

 Previous topic Next topic

This small section is important for guys who are trying to keep up to date with their IT skills as well as

having the latest software versions to work with.

You may be interested to know that I am doing all of this research and development work on a desktop PC

running Windows 8. It is the last version (Release Preview) which is available before the public release version.

Win 8 on a desktop (or laptop) will do all what you were doing in Windows 7, so don't panic.

BUT - the 'Surface' tablet to come shortly from Microsoft, will have a cut-down version of the full Win8 and will

only run METRO style apps - soon to be called 'Modern' style apps because of some legality.

[ .. how about a new name from me ? - of 'MSUI' for "Modern Style User Interface" .. or even just 'MUI' .. ]

Also I am using Visual Studio 11 (which will be known as VS 2012) and this too is the version before the one

just being release as the public version of VS 2012 - this is also the 'Release Preview' I believe.

On top of these two new software platforms I have clean my system of a lot of old SQL Server instances,

and other support 'stuff'.

[ .. although I did my very best to 'cleanse' my system of old instances, I can for some reason seem to be able to ]

[ remove one with '2005' in its name - still its a lot tidier than it was !! .. ]

Now I currently have the new public version of SQL Server 2012 (code named 'Denali') and I have downloaded

and installed both the full version as well as the small light 'localdb' version.

When we do work in these eNotes with SQL Server it will be mostly the full version of 2012, but a little with

the 'localdb' instance as well.

So basically, what I am saying is this, if we can get it running at my end, and the eNotes are all for these

versions of the software tools, then LINQ ought to work for you for a LONG time I should think ;-) Both

with METRO and WPF into the bargain.

I have to encourage all of you to try and upgrade as much as possible, and work with the latest and best

software tools from Microsoft. I moved over from VS2010 to VS11 with no real effort or worries.

Good Luck !

Time to move on a learn something ......... lets get going ............

PHH - 22nd. August 2012.


What is LINQ

What is LINQ

What is LINQ

 Previous topic Next topic

In one sense LINQ is a software technology which vastly improves the data access side of our applications

as far as getting into 'Objects' is concerned.

For years we have been trying to improve our business logics layers with more and better use of objects.

Going from VO to .NET helped me a great deal in this area of coding.

Recently I could improve the GUI side of my app solutions because WPF and now METRO are very much

more 'Object' friendly than WinForms was.

The nested XAML script, and the excellent Dependency System which supports .NET 4.0 data Binding is a

dream to use.

So for me the data access and update layer end of my app solutions needs to be far more 'Object' based.

Recently, in Vulcan.NET (which does not currently have LINQ technology) I have tried to improve the object

approach I take, and designed and made a couple of STATIC classes which go part way towards a LINQ to SQL

approach and solution.

However, I am still working directly with ADO.NET and moving to LINQ will distance, or hide, the ADO.NET

access - which will be most helpful.

PHH - 16th. August 2012.


What can be Queried ?

What can be Queried ?

 Previous topic Next topic

What can be Queried ?

 Previous topic Next topic

Not everything can be queried using LINQ to objects.

Quite simply, the object being queried MUST be a collection.

A series of data items (each being an object) and the collection implements the IEnumerable interface.

It seems obvious when we think about it that each of the objects in the collection is of the same type.

If we are to write query expressions which refer to data properties (or columns/fields in SQL tables) then

the properties we refer to MUST exist for each single object in the collection.

PHH - 12th. August 2012.


Do I/we need LINQ ?

Do I/we need LINQ ?

 Previous topic Next topic

Do I/we need LINQ ?

 Previous topic Next topic

Well, I have lived happily without it using .NET and SQL for years.

However, now that I am using C# with METRO, it is available to me for the first time.

Currently Vulcan 2 does not have LINQ capability but it seems to be on the 'to-do' list.

I have to say that it does seem to make life easier, and nicer, and VERY much improves the 'Object'

experience of coding.

From now on I intend to use it everywhere I have the compiler capability.

I liked ADO.NET and got much success with my special STATIC classes - BUT - if we can actually

by-pass much of the ADO.NET stuff then life will indeed improve a whole 'chunk'.

It is my own personal point of view that LINQ does not negate the need to know and understand SQL

querying - a concept or understanding a few guys seem to have.

However, it brings the querying into the coding and also allows us to similarly code for collections, just

as we do for SQL Table objects.

So to some degree it is 'unifying'.

To to summarize - don't think LINQ means you can by-pass learning SQL querying ideas, far from it.

The better you are at SQL querying the better you will be at LINQ.

I feel the reason I have come so far in a week with LINQ is because I have a really good and solid background

in using SQL querying in the Management Studio environment.

PHH - 11th. August 2012.


SQL query statements

SQL query statements

SQL query statements

 Previous topic Next topic

MSSS = "Microsoft SQL Server"

I have a good friend and colleague who professes to 'Love LINQ and hate SQL statements' and so I am now

quite unsure of what I was about to tell you.

Because I have a pretty solid background in designing and using SQL statements with Management Studio,

for SQL Server (MSSS) flavours 2005 through to the current version called 'Denali' released in 2012, it is

my considered opinion that it greatly helps to have some sort of a grounding in SQL statement use.

Although a new guy coming to LINQ can learn how to use it successfully throughout .NET, it won't hurt

one bit if he has prior knowledge of SQL querying.

Since Microsoft came up with SQL Server many years before they did LINQ on a public platform, I would

suggest that much of LINQ is based on their SQL products.

Personally, I think the SQL Statement is quite beautiful once you get a few years under your belt ;-0) And

I also think some folk 'hate' it because they are frustrated by it and can't get to grips with it in half and hour.

The reason the fail, and get frustrated is because the full range of possibilities in querying is rather LARGE

or WIDE !

Yes, you have guessed it, the next thing I will say is that they is a LOT to learning LINQ too, if we are to get

to the same reasonable competence of our (sorry mine) SQL querying skill level.

If you wish to learn more of standard MSSS querying skills then consult 'ClickStartTSQL' eNotes which are

pointed to in the next but one subsection.

Good News :

Yes, there is always Good News, if you look at things the right way around ;-)

It is VERY easy to get into LINQ usage with .NET and C#. We can start to get results almost immediately.

Lets get going, and move on to do some 'stuff' ...............

PHH - 11th. August 2012.


Books and eBooks

Books and eBooks

Books and eBooks

 Previous topic Next topic

I include in this subsection details of the three books and eBook which I used to learn LINQ.

They seem to be serving me very well as currently I am over half way and going along nicely.

The first two publications I got in hard copy format - i.e. 'Books' to you and me. The third one

I got in eBook (PDF) format only, as I find it easier to work on my three screens that way.

========================================================================

==================================================================================================================================================================

I bought this next book a while back but it is still most useful :-

========================================================================

ISBN 13 : 978-0-7356-2391-0

==========================================================================

Now the eBook format :

=======================================================================

I got my eBook from O'Reilly - an on-line purchase.

ISBN : 978-0-735-64057-3

===========================================================

=================================================================

PHH - 16th. August 2012.


Other Learning Materials

Other Learning Materials

Other Learning Materials

 Previous topic Next topic

'ClickStart' eVolumes - me web site :

http://www.winclickstartvulcan2.net/ClickStartExec2.html?introduction.htm

==========================================================================================

Note the date above was when the page was first put together, it has had a LOT of updates since then, and the last two entries

are in fact VERY recent - like August 2012.

The T-SQL and ADO.NET eVolumes may be most use to you as these are related to SQL Server coding and querying.

Other sites for 'ClickStart' :

The earlier versions and / or titles of my ClickStart eNotes were placed on a web server which was not running Windows.

This site is seen below, along with a front screen of what is on offer. The work tends to be .NET 2.0 and WinForms based.

http://www.clickstartvulcan2.net/

=====================================================================================

The modern Windows based web site at

http://www.winclickstartvulcan2.net/ClickStartExec2.html?introduction.htm

will tend to have material refreshed and uploaded almost every day - and what is updated and improved depends on what

I am working on at the time. Currently this is LINQ, METRO and soon MvvmLight (MVVM).

Enjoy your learning !

PHH - 16th. August 2012.

Addendum - LINQPad4 :

I found this VERY useful software tool yesterday - at http://www.linqpad.net/

As well as being a tool to use for real work, it has lots of samples available and support learning material too.

You can go wrong with this - and the standard version is a FREE download.

====================================================================================================================================================================

And here is a small sample of my own success, although I have to confess that I have as yet done very little with it.

===================================================================================================================================================================

Once I saw how good this tool was, and that Eric Nelson of MS gave it the thumbs up, I decided to

support the guys who made it and buy the Premium Edition. After all, LINQ will hardly be going away ;-)

Certainly you need to get the standard edition ASAP.

I will add a subsection somewhere in these eNotes about getting going with LINQPad4.

Time to move on ......................

PHH - 22nd. August 2012.

Addendum :

Here is what Julia Lerman has to say on LINQPad :-

====================================================================================================================


Setting up a SQL Server and a DB

Setting up a SQL Server and a DB

Setting up a SQL Server and a DB

 Previous topic Next topic

In this subsection I will discuss the details of how to set up both the latest SQL Server from Microsoft,

as well as acquiring a suitable database from the web.

When I write this the 'Denali' version of Microsoft's SQL Server (MSSS) has been out for a few months.

The version of MSSS code named 'Denali' is 'Server 2012'.

I have tested the download and install for 'Denali' and the free Express version is relatively easy to both

acquire from the web, and also install. They (Microsoft) have improved things a lot over earlier versions,

I know, I have the bruises to prove it ;-)

However, if you download and install the 'local' version of MSSS 2012, it is even easier - and quite idea for

doing local development and testing.

Downloading SQL Server 2012 Express :

Currently the following URL seems to be the one to have and use :-

http://www.microsoft.com/en-gb/download/details.aspx?id=29062

The Express version does everything the Full version does, and the DB size limit is actually quite HUGE really -

something like ten Gigs - certainly plenty for testing and trialling, as well as small business use - in accordance with

the Microsoft licensing.

Choose the version of download which suits your hardware - see below :-

=================================================================================================================================================================

In fact I also draw your attention to the small files of around 30 Megs or so. These are labelled as 'SqlLocalDB' and

are for you to select from on the basis of your hardware - once again.

I do suggest you download the one for you, as well as install it, this is the new part of helping developer guys get going with

SQL Server, and for ease of transfer to a customer's on-site location.

We will deal with 'Local' DB later, and it may be the answer to getting METRO up and running too :-)

Certainly, 'LoaclDB' is the very easiest to install, I am not sure that I had to do anything. And the server name is

then a fixed value for all installations - see below :-

==========================================================================

On the PC platform I have in front of me the 'localdb' connection opens in Management Studio (MS)

as shown below :-

=================================================================================

The eagle eyed amongst you will notice that I now have two Servers open in MS, the full version and the

local one.

Now for a sample database ............

Suitable Database - AdventureWorks2012 :

I Googled the web to find the Codeplex URL shown below :-

http://msftdbprodsamples.codeplex.com/releases/view/55330

At this link there are a host of database related files on offer - I think I chose the top, or first, one

on offer - see below :-

================================================================================================

You will get Management Studio along with the full version, it will be most helpful to you if you make sure

you have it installed and that you place it on your desktop or task bar for quick and easy access.

Also make sure you set MS to load up with you using it as Administrator - or with Administrator rights.

So after download, and 'saving', and my 'Download' folder looks like this - see the next image :-

============================================================================================================================================================

Now you need to place this file somewhere more suitable - a folder with security set for user access.

The 'tricky bit' - Placing it in an Accessible Folder :

Now the 'security' reality, we must have the DB file in a folder that the Windows system knows we have full permissions for.

As we have moved through Vista, and Windows 7, to now the Beta of Win8 I am using, the security issues and access rights

'things' have gotten tighter and tighter.

So basically, if I can get W8 working with AW12 and MSSS 2012, then at least you can too.

I usually try to attached the DB file in my chosen folder, via Management Studio

Okay then, before we can 'attach' a file to Management Studio as long as we place it in a folder with full access rights.

See the image below in which we are viewing folder named 'D:\SQLdatabases\' :-

====================================================================================================================

And if I show you the properties dialog for this folder (obtained by right clicking the folder in Windows Explorer, we

see the following image on my PC platform :-

=====================================================================

Make sure you allow full control for all your groups and users - just to be on the safe side!

Now we need to move on to trying to 'attach' the file in MS.

'Attaching' a Database in Management Studio :

*** word of warning *** when attaching a DB to a server, it can be a 'tricky' task. Although I

have been doing this for years I still don't quite know what makes the system 'tick', or how

it actually works - I just survive, and on a good day make it work ;-0)

However, a few simple tips are - don't attach the same '.mdf' file to two different SQL Servers.

Also, if you use MS to create a new database, make sure you detach it and then re-attach it

again, before you try to use .NET code access.

For some reason on my system, if I make a new DB then immediately try to access it from code,

I get an error. But when I detach it first it then works OK, and then I can re-attach it and the

code still works. 'Funny old world! '.

Right click the 'Databases' node in the 'Object Explorer' (OE) pane, as seen below :-

================================================================================

When you click the 'Attach' option you get a dialog screen, from which we need to click the 'Add'

button to bring up a selection dialog - see below :-

==================================================================================================

I have made sure that I detached the AW12 file first - from the full MSSS.

The results are seen in the next image :-

===================================================================

Yep! unfortunately, the MS 'shell' system makes a long DB name as seen above - but don't worry,

it does not cause a problem.

However, one thing you need to know, and worry about ?, is how to reduce the OE pane content by

setting a 'Filter'.

In the above image we see only the tables in the 'Person' schema, and this is done by right clicking

in the 'Tables' node of the OE pane and following the obvious selection - see below :-

=============================================================================

This is a useful feature of MS and filtering can be done on file name and or schema name.

Checkout the next image see below :-

===========================================================================

And just to check that things are fully OK you can right click the 'Person.Person' node in the

OE pane and get the first 1000 rows (max) to display in a tab output pane on the RHS.

Here is what is needed - see below :-

======================================================

In the following image I have edited the query - removed a few not so interesting fields, and

change the 'Top 1000' restriction, so we see in bottom right that we have almost 20,000 rows :-

And here is an image of the general layout for our display :-

==========================================================================================================================================================================

I find it VERY useful to have MS up on screen while I do any SQL work at all, coding or 'Reporting Services' work.

Don't worry however, the MS shell does NOT keep an open connection to the database.

Now, if you are worrying about connections to the DB from .NET code, and how we find out what the

connection string has to be for our system, don't !!

We will cover making a connection in Appendix C - entitled 'SQL Server Connecting! '

Time to move on, see you in the next subsection ....................

PHH - 17th. August 2012.

*** WARNING *** There is some restriction on the connections allowed to the 'localdb'.

You need to check on this but it looks to me as if only ONE can be made, so having Management

Studio and your .NET app using it can be a problem - I was struggling yesterday, attaching and detaching etc..

One idea for exploration of AW12 is to have a full version of Server 2012 with AW12 attached, and you to access the

data from your .NET app with a 'localdb' server connection.

This all depends on whether the same database can be accessed from 'localdb' as well as 'full version'. When I started

to explore 'localdb' a while back there we VERY little information available - sorry !


Chapter 0 -

ClickStartLINQ

Chapter 0 - Making a Start

Chapter 0 - Making a Start

 Previous topic Next topic

Chapter 0 - Making a Start

 Previous topic Next topic

Well guys, lets get one thing quite straight, LINQ is in Microsoft's C# / VB.net languages.

It seems to be part of the .NET framework, and also needs to be a feature within the flavours

of their compilers too. Or another compiler like that of Vulcan.NET.

However, because this LINQ stuff is more about the data end of things, it does not get mixed up

with the GUI format being used. So it will work with WPF, WinForms, Silverlight and now METRO.

Currently, as I write this, I have done just about half of these eNotes using METRO as a platform in

VS11, simply because that is what was there in my Visual Studio 'shell'.

However, now that I am moving onto "LINQ to SQL", and the sections related to that, I am going to

witch over to WPF with .NET 4.0 and C# to do these next bits of my learning.

Hopefully, in the near future, I will be able to add a section on using WPF with Vulcan.NET and enjoy

myself doing so.

For the moment however, we will use VS11 and METRO as a platform to explore LINQ with 'Objects'.

By this we mean we will have collections of custom / business objects and use LINQ syntax to do

some VERY useful things with these - writing code which will also be checked by the compiler, and

which will also be like that we use when we come to using SQL and entities based on SQL Tables.

Let's get our sleeves rolled up and get going ;-0)

PHH - 16th. August 2012.


Starting a New Project

Starting a New Project

Starting a New Project

 Previous topic Next topic

*** Note *** If you have not got VS11 and METRO with Windows 8 then you can still do all of this

stuff with WPF / WinForms and Visual Studio 2010.

In fact the beta VS11 will work in Windows 7, it will just have the METRO templates missing.

======================================================================

Open Visual studio 11 (2012) and close any solution/project which is open.

Chose from File, New, and Project, as see below :-

=======================================================================================

And then at the 'New Project' dialog screen make the following choices, those seen below :-

=======================================================================================================================

Notice that we have named our new project 'LINQ2METRO' and that we have selected a 'Blank App' template.

To see more detail on creating and starting new METRO apps consult 'ClickStartMETRO' from my web site.

If you have followed me then you should have something like the following on your desktop screen :-

=====================================================

Now expand the 'MainPage' folder or 'node' in the Solution Explorer (SE) pane, and change the background colour

as shown in the next image, shown below :-

======================================================================================================

Okay that is fine, and we have a start - BUT - where are we headed ? ..................

What we are about to do ? :

Well, since we are about to do some tests and trials with Collections of custom objects, we need at least one

'ListBox' control in which we can display our 'View' of the Collection, and also at least one 'TextBlock' control in which

we can display any text output regarding what is happening, or what we are doing.

But first, thinking ahead, we may be well advised to add a grid of columns and rows first, before we do anything else.

Take a careful look at the following image and see we have so far added 5 columns and 11 rows :-

=============================================================================

So then, now we have a suitable grid we can add a ListBox control - I do this manually, editing the XAML script

directly within the editor - checkout the details below :-

===============================================================================================================

Once we have our ListBox showing OK, we then need to add the TextBlock.

Look at the next image and copy what I have added - using the script editor directly :-

========================================================================================================================

Yes, you will have noticed that I added a Name attribute to both ListBox and TextBlock - this will come in useful when we do

some data binding and the simplest and most direct way.

We will carry out good data binding but keep our events local to the Page. Also we will bind directly to the controls and not have

one object which we bind to the Page. That would be rather cumbersome for just a small demo app and a simple screen (Page).

For more detailed information on binding and a move to MVVM then see the ClickStartMETRO eNotes on my web site.

Okay then, lets compile and run with the debug facility enabled. Study the following image and make your selection similar :-

================================================

Once the 'Simulator' text is showing in the box, click it with the mouse to launch both the app and the Simulator itself.

This is what I have at my end of things :-

Don't worry about the cross and the square, we can get rid of that later.

To stop debugging we will need to remember to click the dark red square in the menu bar.

The next image will prompt you as to where to go and what to look for :-

==================================================

Moving on :

Now move to the C# code behind the 'MainPage', and in the editor clean it up to look like the following :-

===============================================================================================

Before we move to the next subsection to make some suitable data items, we need to have some visual success

I feel, so lets bind some simple string data to the TextBlock control via the Text attribute.

Below is what I have now - BUT - I did get a bit of a shock earlier when I seemed to get 'nothing' on screen and in the

TextBlock area, when I compiled and ran the app. - problem was I did not colour my text output ;-0))

Checkout the following image where at least we can read some message data :-

And to see the XAML script which goes with this checkout the image below :-

==================================================================================================================

The other half of the 'binding' is done in the C# code and I have simply added this to the constructor - see the following :-

===============================================================================================================================================

Okay then, some visual success in METRO - great stuff - now to make some data which will

help us get even more success, some of which will be on a LINQ level.

See you in the next subsection ...............

PHH - 11th. August 2012.

Addendum :

While we have the chance, let us see how to use the Escape sequence approach to adding a couple of line breaks

or carriage returns as we often call them.

In the image shown below we have added ' \n\n ' where ' n ' stands for 'New Line'. Check it out now :-

====================================================================================================================================================

The result of this extra escape sequence is shown below :-

=================================================================================================

We will see other escape sequences as we go through these eNotes, watch out for them.


Creating some Data Objects

Creating some Data Objects

Creating some Data Objects

 Previous topic Next topic

'LINQ to Objects' is the part of LINQ which works with in-memory collections.

For the moment we will use List<T> as our 'collection', but will look at the whole (and full) range of

possible collection 'types' in a later section.

Objects which implement the 'IEnumerable<T>' interface are those we are referring to - AND - these are

generally called 'sequences' in LINQ parlance apparently.

Remember that 'ObservableCollection' objects can be made by instantiating using a List<T> object as

a parameter for the 'constructor'. So if we cover List<T> then we also cover ObservableCollection objects

as well.

Where to Start :

Before we make any list, arrays or collections, we first need a few (2 or 3) suitable, but simple enough,

custom classes, from which to objects to place in a collection. (Or from which to make a 'sequence'.)

In the SE pane lets make a new folder (or node) and call it 'OurClasses'.

Here is my new folder :-

===============================================

And then right click in the folder within the SE pane and add a new code file as shown below :-

=============================================================================================================

The stub file you are made by the template is as you see in the following image :-

======================================================================================

And now we need to design and structure our class of 'Customer' such that it is a 'good citizen' of the Dependency

System of the WPF and METRO world.

Once again full details of Dependency Objects and Dependency Properties are included in the ClickStart

eNotes on METRO and WPF, and XAML too.

First of all, before we look at the working code for class 'Customer', let us see some visual success ;-)

Checkout the following runtime image :-

======================================

This is a result of the 'ToString' method in our new class of 'Customer' - see the code snippet below :-

======================================================================================================

And now we had better view the full code for this new class - check this out carefully :-

=========================================================================================================================

Okay then, don't panic, the above class is explained in my other eNotes, and is as complex as is needed to make

data binding through the dependency system work correctly.

It is quite possible to copy and adapt this class to suit your own needs - I know, I did exactly that when I started Data Binding !!

So how did we supply some customer details ?

Simple, we use the non-empty form of the constructor, at the start of the 'MainPage' coding - see below :-

================================================================================================================================

Now for the last part of this construction of data objects subsection.

If we can make one Customer object, then we can make a whole bunch. And, we can put the bunch into a typed List as well.

The best thing for this task is a STATIC method - which we can put into the folder we already have, called 'OurClasses'.

What we will do is make a new class called 'StaticDataTools.cs' and then add STATIC methods as we require them.

Here is what I have, which seems to work nicely :-

===============================================

The following image shows the 'StaticDataTools' class, the one into which we will add a few STATIC methods to

supply us with collections / lists of custom objects.

Obviously, in the following image the 'ListOfCustomers' method returns a List<Customer> object :-

==========================================================================================================================================================================

Once we know this works OK we can improve it by adding more and varied data items.

First of all lets look at the 'raw' output when we bind it to our 'ListBox' control :-

================================================================

Okay then, nothing too clever, and the font is too small as well.

However, we can soon improve both of these aspects - more data and varied too - and a bigger font size ;-)

First see how we bind the 'sequence' or collection to the GUI control - check this out :-

=========================================================================================================================================

So now we can bind a whole collection to our list box, lets make a much larger set of data, so we can

then use it as input for our query expressions.

Well, here is more data for you, even though we have yet to improve the font, using a data template.

Check this out :-

===============================================================

And now the code which produced the list display is see below :-

======================================================================================================================================================================

Okay the guys, I have had to make a few smaller adjustments, as well as an odd correction in the data, but

the biggest changes are to do with the resources that have been added.

First lets look at the success at runtime - check this out below :-

===========================================================================================

Well, it seems to look something like the data we included in our C# code to create a collection.

And now we need to focus our attention on the 'Style' and 'DataTemplate' which has been used to make our

visual display look as good as it is - study this XAML script carefully :-

==========================================================================================================

In the above image notice that the 'DataTemplate' refers to the 'Style' with the Key value of 'CustomerListItem'.

Later we will place our Styles and Templates in a Resources Dictionary to help make our GUI controls scripting

a bit clearer. However, all the METRO stuff is covered in much more detail in the 'ClickStartMETRO' eNotes.

And here is how we apply the template (with Key value 'CustomerDatTemp' ) to the control :-

==============================================================================================================

Please also note that in the above image the script could also be written with the 'ResourceKey=' text being removed.

It is an alternative syntax variation to be able to drop this text in the same way as it is an alternative to drop 'Path=' in

the extension syntax for 'binding'.

When possible I will include the full syntax, or even use both so that you are at least aware of what can be written in

sample script you see in examples by other guys.

Where from here ? :

Well now, since we have a collection of similar data items, and that we can display these on a Page for viewing, what

we now need to explore is how we can apply query expressions and operators to our collections, in order to make

others for display on our GUI surface.

Just before we move on to make some complementary classes, so we can do 'Join' etc. in the future sections, let us

take a moment to see where we may be headed. Let's see a meaningful and straightforward example, based on the

Customers collection we now have working for us.

Look at the output shown below and note the postcodes as well as seeing the sort order of the Names :-

==============================================================================

The code used to reduce the full 'raw' data list of items to just four is show in the following image of the XAML script :-

=======================================================================================================================

Notice that for simple convenience at the moment, we have added the necessary code lines to the constructor

for the 'MainPage'.

So to summarise, the lines numbered 28 through 32 are those which take the original collection and then

after applying logical conditions to the data item properties, create a 'view' collection to be displayed on the GUI.

So 28-32 is our query expression, and we will explore in much more detail what we can include in the query section.

Just before we move on we need to remind ourselves that there is an alternative LINQ syntax to get to know, and one

which many either prefer or like very much ;-)

It is the syntax using Lambda expressions and Method operators - below is the same query written in this allternative

fashion, so study it carefully :-

========================================================================================================================

Okay then, the code above makes good sense, and can be seen to be the equivalent to the QE (query expression) code we

used for the first querying results.

Compare lines 33 through 36 with those of 28-32 in the previous query test.

Time to move on ....................

PHH - 11th. August 2012.


Creating other classes

Creating other classes

Creating other classes

 Previous topic Next topic

So far, so good, we have a Customer class.

However, before we can do any interesting querying, we do need to have other classes which we can use

in a meaningful way with our 'Customer' class.

Lets say we need an 'Order' class, and an 'OrderItem' class, as well as a 'Product' class. We will make sure that

each has a unique identifier as one of the fields, or in our case of in-memory objects, one of the 'properties'.

We will also make sure we do a sensible amount of 'normalising', and provide foreign keys as well as primary ones.

If we design and construct good examples of classes to use in our testing, combined with some sensible items

of data within each object, then the example queries will make much more sense to us, and we will see more

clearly what is going on.

So lets get to work !

Creating an 'Order' class :

In the Solution Explorer (SE) pane, highlight the 'OurClasses' folder (or node) and right click for the context menu.

Choose to Add a New Item and bring up the following dialog screen :-

=============================================================================================================

Select to start a new C# code class, and provide a suitable name - in this case 'Order'.

I now have my SE pane looking like this below :-

===================================================

And the new template 'stub' looks as the following image :-

========================================================

I will now decide upon some useful properties, and make then DPs as we did for our Customer class.

Give me a few minutes while I go 'design' ;-)

===================================================================================================================

====================================================================================================================

===================================================================

===========================================================================================================

=====================================================================================================================

===================================================================

=========================================================================================================================

Notice in the above image that there are two ways add a new order data item. Lines 45-47 show the more succinct way

of adding an item - however, this can get a bit cumbersome if there are many parameters to input.

Although we now seem to have quite a few order items - we can see eleven above - we will need more to be added later

if we are to make meaningful query tests at a later stage.

Before we think of more data items for Orders, let us move on to making a 'Product' and then 'OrderItem' class.

'Product' class :

'OrderItem' class :

PHH - 11th. August 2012.


working code

working code

working code

 Previous topic Next topic

=====================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

//===============================

using System.ComponentModel;

using Windows.UI.Xaml;

namespace LINQ2METRO.OurClasses

{

    class Customer : DependencyObject, INotifyPropertyChanged

    {

        public static DependencyProperty CustomerIDProperty = DependencyProperty.Register("CustomerID", typeof(string), typeof(OurClasses.Customer), null);

        public static DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(OurClasses.Customer),

                        new PropertyMetadata(""));

        public static DependencyProperty AddressProperty = DependencyProperty.Register("Address", typeof(string), typeof(OurClasses.Customer),

                        new PropertyMetadata(""));

        public static DependencyProperty PostcodeProperty = DependencyProperty.Register("Postcode", typeof(string), typeof(OurClasses.Customer), null);

        public static DependencyProperty CreditLimitProperty = DependencyProperty.Register("CreditLimit", typeof(double), typeof(OurClasses.Customer),

                        new PropertyMetadata(-1.23));

        public static DependencyProperty DateNewProperty = DependencyProperty.Register("DateNew", typeof(DateTime), typeof(OurClasses.Customer),

                        new PropertyMetadata(new DateTime(1900,01,01)));

        public static DependencyProperty ActiveProperty = DependencyProperty.Register("Active", typeof(Boolean), typeof(OurClasses.Customer),

                        new PropertyMetadata(true));

        //----- Events -----

        public event PropertyChangedEventHandler PropertyChanged;

        //=======================================================

        //----- Constructors -----

        public Customer()

        {

            //----- make initial settings ! -----

        }

        public Customer(string cID, string cN, string cA, string cP, Double nCL , DateTime dtN , Boolean lA  )

        {

            //----- make initial settings ! -----

            this.CustomerID = cID;

            this.Name = cN;

            this.Address = cA;

            this.Postcode = cP;

            this.CreditLimit = nCL;

            this.DateNew = dtN;

            this.Active = lA;

        }

        //=======================================================

        //----- methods -----

        public override string ToString()

        {

            return this.CustomerID + " | " + this.Name + " | " + this.Postcode ;

        }

        //----- Properties -----

        public string CustomerID

        {

            get { return (string)GetValue(CustomerIDProperty); }

            set { SetValue(CustomerIDProperty, value); OnPropertyChanged("CustomerID"); }

        }

        public string Name

        {

            get { return (string)GetValue(NameProperty); }

            set { SetValue(NameProperty, value); OnPropertyChanged("Name"); }

        }

        public string Address

        {

            get { return (string)GetValue(AddressProperty); }

            set { SetValue(AddressProperty, value); OnPropertyChanged("Address"); }

        }

        public string Postcode

        {

            get { return (string)GetValue(PostcodeProperty); }

            set { SetValue(PostcodeProperty, value); OnPropertyChanged("Postcode"); }

        }

        public double CreditLimit

        {

            get { return (double)GetValue(CreditLimitProperty); }

            set { SetValue(CreditLimitProperty, value); OnPropertyChanged("CreditLimit"); }

        }

        public DateTime DateNew

        {

            get { return (DateTime)GetValue(DateNewProperty); }

            set { SetValue(DateNewProperty, value); OnPropertyChanged("DateNew"); }

        }

        public Boolean Active

        {

            get { return (Boolean)GetValue(ActiveProperty); }

            set { SetValue(ActiveProperty, value);  OnPropertyChanged("Active"); }

        }

        //=========================================================================

        //----- Create the OnPropertyChanged method to raise the event -----

        protected void OnPropertyChanged(string name)

        {

            PropertyChangedEventHandler handler = this.PropertyChanged;

            if (handler != null)

            { handler(this, new PropertyChangedEventArgs(name)); }

        }

    }

}

=====================================================================================

using System;

using System.Collections.Generic;

//-------------------------------------

using System.ComponentModel;

using Windows.UI.Xaml;

using System.Collections.ObjectModel;

namespace LINQ2METRO .OurClasses

{

    class StaticDataTools

    {

        public StaticDataTools()

        {

            //----- empty constructor -----

        }

        public static List<OurClasses.Order> ListOfOrders()

        {

            List<OurClasses.Order> aList = new List<OurClasses.Order>();

            //--------------------------------------------------------------

            OurClasses.Order D1 =

            new OurClasses.Order("d001", "c001", new DateTime(2011, 03, 13), "u013" ,true);

            aList.Add(D1);

            OurClasses.Order D2 =

            new OurClasses.Order("d002", "c005", new DateTime(2011, 05, 23), "u013" ,true);

            aList.Add(D2);

            //-------------------------------

            return aList;

        }

        public static List<OurClasses.Customer> ListOfCustomers()

        {

            List<OurClasses.Customer> aList = new List<OurClasses.Customer>();

            //--------------------------------------------------------------

            OurClasses.Customer C1 =

            new OurClasses.Customer("c001", "Jones", "13 Front Street, Someplace", "NP12 7TY", 34.56, new DateTime(2011, 03, 13), true);

            aList.Add(C1);

            OurClasses.Customer C2 =

            new OurClasses.Customer("c003", "Smith", "36 Back Alley, Cardiff", "CF14 3BQ", 60.00, new DateTime(2009, 08, 23), true);

            aList.Add(C2);

             OurClasses.Customer C3 =

            new OurClasses.Customer("c005", "Williams", "37 Commercial Road, Newport", "NP11 3RT", 70.00, new DateTime(2007, 01, 14), true);

            aList.Add(C3);

            OurClasses.Customer C4 =

            new OurClasses.Customer("c007", "Smythe", "45 The Crescent, Cardiff", "CF14 3BQ", 80.00, new DateTime(2009, 10, 17), true);

            aList.Add(C4);

             OurClasses.Customer C5 =

            new OurClasses.Customer("c009", "Brown", "19 Spring Avenue, Someplace", "NP12 7TY", 300.00, new DateTime(2012, 02, 27), true);

            aList.Add(C5);

            OurClasses.Customer C6 =

            new OurClasses.Customer("c011", "Green", "23 The Place, Cardiff", "CF11 2ED", 200.00, new DateTime(2006, 05, 11), false);

            aList.Add(C6);

            OurClasses.Customer C7 =

            new OurClasses.Customer("c013", "Brown", "29 Spring Avenue, Someplace", "NP12 7TY", 100.00, new DateTime(2012, 02, 27), true);

            aList.Add(C7);

            //-------------------------------

            return aList;

        }

    }

}

=====================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

//===============================

using System.ComponentModel;

using Windows.UI.Xaml;

namespace LINQ2METRO.OurClasses

{

    class Order : DependencyObject, INotifyPropertyChanged

    {

        public static DependencyProperty OrderIDProperty = DependencyProperty.Register("OrderID", typeof(string), typeof(OurClasses.Order), null);

        public static DependencyProperty CustomerIDProperty = DependencyProperty.Register("CustomerID", typeof(string), typeof(OurClasses.Order), null);

        public static DependencyProperty OrderDateProperty = DependencyProperty.Register("OrderDate", typeof(DateTime), typeof(OurClasses.Order),

                        new PropertyMetadata(new DateTime(1900, 01, 01)));

        public static DependencyProperty MadeByIDProperty = DependencyProperty.Register("MadeByID", typeof(string), typeof(OurClasses.Order),

                        new PropertyMetadata("..xyz.."));

        public static DependencyProperty ActiveProperty = DependencyProperty.Register("Active", typeof(Boolean), typeof(OurClasses.Order),

                        new PropertyMetadata(true));

        //----- Events -----

        public event PropertyChangedEventHandler PropertyChanged;

        //=======================================================

        //----- Constructors -----

        public Order()

        {

            //----- make initial settings ! -----

        }

        public Order(string cOID, string cCID, DateTime dtOD, string cMB, Boolean lA )

        {

            //----- make initial settings ! -----

            this.OrderID = cOID;

            this.CustomerID = cCID;

            this.OrderDate = dtOD;

            this.MadeByID = cMB;

            this.Active = lA;

        }

        //=======================================================

        //----- methods -----

        public override string ToString()

        {

            return this.OrderID + " | " + this.CustomerID + " | " + this.OrderDate.ToString();

        }

        //=======================================================

        //----- Properties -----

        public string OrderID

        {

            get { return (string)GetValue(OrderIDProperty); }

            set { SetValue(OrderIDProperty, value); OnPropertyChanged("OrderID"); }

        }

        public string CustomerID

        {

            get { return (string)GetValue(CustomerIDProperty); }

            set { SetValue(CustomerIDProperty, value); OnPropertyChanged("CustomerID"); }

        }

            public DateTime OrderDate

        {

            get { return (DateTime)GetValue(OrderDateProperty); }

            set { SetValue(OrderDateProperty, value); OnPropertyChanged("OrderDate"); }

        }

        public string MadeByID

        {

            get { return (string)GetValue(MadeByIDProperty); }

            set { SetValue(MadeByIDProperty, value); OnPropertyChanged("MadeByID"); }

        }

        public Boolean Active

        {

            get { return (Boolean)GetValue(ActiveProperty); }

            set { SetValue(ActiveProperty, value); OnPropertyChanged("Active"); }

        }

        //=========================================================================

        //----- Create the OnPropertyChanged method to raise the event -----

        protected void OnPropertyChanged(string name)

        {

            PropertyChangedEventHandler handler = this.PropertyChanged;

            if (handler != null)

            { handler(this, new PropertyChangedEventArgs(name)); }

        }

    }

}

=====================================================================================

=====================================================================================

PHH - 11th. August 2012.


Getting some results

Getting some results

Getting some results

 Previous topic Next topic

PHH - 11th. August 2012.


Chapter 1 -

ClickStartLINQ

Chapter 1 - Collections

Chapter 1 - Collections

 Previous topic Next topic

Chapter 1 - Collections

 Previous topic Next topic

Hi folks, the point of this whole section on collections is to show you the common ones used

primarily with business .NET solutions, and also with Custom classes of objects.

By custom classes I mean those we as developer create to solve our business needs, like 'Customers',

'Invoices', 'PoorPayers', 'Products' and similar ones.

It is not my intention to cover all collection types, and particularly some 'older' ones, and those not so

regularly used in data processing - you can look into Stack, Queue, and Dictionary stuff yourselves.

I will concentrate on List<T> and ObservableCollection<T> as well as suggesting that you give up, when

at all possible, using Array and ArrayList classes. There are definite benefits in doing so.

First of all, let us see what the SDK docs have to say in MSDN from 'HelpViewer' 2.0 and VS 2012 :-

======================================================================================================================================

We will see what this means as we go along in this chapter and its subsections.

Here is some more detail we ought to look over :-

===================================================================================================================================================================

=============================================

========================================================================================================================

====================================================================================================================

PHH - 30th. March 2013.


which syntax to use ?

which syntax to use ?

 Previous topic Next topic

which syntax to use ?

 Previous topic Next topic

Let us start out by seeing what Microsoft have to say about this apparent 'dualism' in the

choice of coding styles and approach to LINQ querying.

This is from MSDN notes in VS 2012 :-

=====================================================================================================================================

So to put this imply, MS had to incorporate the Extension methods into the supporting C# and .NET technologies, before

the could add to the compiler the preferred 'LINQ declarative query syntax'.

If you know anything about computer languages then you will be fully aware that a 'declarative' language is that

of choice of those that know about these things.

A declarative style is used to describe the problem and its solution in general terms - not by the style of

telling the computer what to do, in a step by step fashion.

Let us now compare a sample or two, so that we can see what the two styles look like.

Personally I find the 'query syntax' simpler and clearer to read, and to create as well.

However, there are lots of eBooks in which we are forced to read and digest the Lambda expression methods.

Below I have provided the code from a real life data logging application, and I have used no Lambda expressions

at all in the code solution - check this VERY carefully :-

==============================================================================================================================

The above code reads as easily as T-SQL and in many ways better than it.

I like the way that it is easy to code a subsequent query from any earlier one, this means we do

not have to deal with all the issues at once. More of this later when we look at complex querying.

Before I move on to show you a sample of Lambda expressions at work, let me include an image of the 'SensorGroup_A'

class which we use above :-

==================================================================

Lets move on a pace ................

Lambda Expressions and their Syntax :

I have to confess that because I prefer 'query syntax' I have written most of my 'real life' apps using

it, so have few Lambda expression method sample to show you :((

So you will have to put up with an example which is not so extensive, and potentially as interesting as

the previous one.

Study the following details carefully :-

===============================================================================================================================================================================================

Because the example is small, and we have only four Lambda expression methods, two of which

take no arguments, the less readability of the example is not THAT apparent.

However, we will progress.

Look at the results of this code and note it is the first column, for ReadingID, which is sorted (high to low) :-

=================================================================

Now let us change the order of application of the extension methods - just to show that it is

possible - particularly for the 'Distinct' method.

Look in detail at the next Lambda query and see that we have now forced the ordering methods

to come last in the sequence - this will ensure the correct ordering of items in the collection.

Note also how we can line up vertically all of the Lambda methods, as well as that we have now

changed the field (column) on which we are sorting.

Checkout the following in detail :-

==============================================================================================================================

And the resulting data grid looks like this :-

=========================================================================

Note above the 'Value' column - it goes from small to large as we descend.

To help me with the Lambda comparison I have looked to one of my many eBooks. Try the following section ..........

Another 'slant' :

To help us understand the two syntaxes, here is a quote from the eBook by Pialosi and Russo :-

[ .. their book is "Programming Microsoft LINQ in the .NET Framework"]

=======================================================================================================================================

I hope this helps in some way or another.

The bottom line as I see it is that Microsoft would not have provided the query syntax if there had not been a

very good reason - after all it cost money and time and effort.

I like the sugary approach, but hope to keep proficient with Lambda stuff so that I may read other

published material.

Time to move on, lets go to the next subsection .................

PHH - 31st. March 2013.


a Simple example to start

a Simple example to start

a Simple example to start

 Previous topic Next topic

If we approach the subject of Collections in the wrong way it can appear to be quite complicated.

However, this is not necessary - we can study a few useful examples and then adapt and copy, and

then we quite quickly get results ;-)

Because collections of one sort or another were there at the beginning of .NET, and that other, and

possibly more useful, collection types have been introduced as .NET developed, we can in fact restrict

ourselves to a few types and be able to do a LOT of useful 'stuff'.

However, with List<T>, ObservableCollection<T> and 'query' from LINQ, we can do almost anything.

So all our examples will be dealing with in memory objects - collections are indeed many objects grouped

together as one object.

Quite often the most useful I find is the collection of one specific type of 'item' class. So the collection is

a bunch of similar, usually custom, objects.

I will show you some basic things using a custom class of mine called 'ReadingNew'.

Look at, and study, the following image which shows a data grid bound to a typed List with seven items :-

======================================================================================================

In the above image each item is actually a 'ReadingNew' object.

We will only be using the first four columns (fields) for test data values.

Now then, we need to see the code which created the collection, the typed List. The type being 'ReadingNew'.

Checkout the following details thoroughly :-

=====================================================================================================================================

Line 54 above is to finish the binding of the List to the 'DataGrid' control.

Note in the next image the attribute at the start of line number 9. The other attributes are to make the

data grid element appear as it does in the image displays - above and below.

============================================================================================

So lets now go a bit further, and sort the list items by Value ascending (high to low), and by using

the functionality built into the data grid headers :-

===========================================

As you will see quite soon, we can actually do the same sorting using C# code.

For the moment, let us see how easy it is to code things so we can find an average across the whole List.

In the following image we see that one line, numbered 56, is required to find the average of the 'Value' field.

Study this carefully :-

=====================================================================================================

The above code uses Lambda expressions and we will learn more about them in a subsequent section.

For the moment (now) just get a feel for how they are applied, and what they do for us.

Now here is the live output when we run the test app. with this code in use :-

============================================

Okay ! I know, we need to round off the value of the average we found ;-)

So here is some extra code which will do that little task for us, check this out :-

===============================================================================================================

And the subsequent average displayed to 3 decimal places is this below :-

===========================

That's better, lets move on a pace or two .............

Maximum and Minimum :

Now then, if we can use one Lambda expression we can then use a least a half a dozen more.

So here below, we find both the maximum and minimum values in the column of 'Sensor_ID' :-

===============================================================================

The Max and Min are just another two of the many available 'Extension' methods.

And this runs to give the following 'test / demo' output :-

===========================

If we wish to know the number of terms in the list we use the 'Count' property as seen next :-

================================================================================================

And now below how this looks on our app form - of type WPF :-

======================================

Lets move on another pace ............

Setting an Order :

Okay then folks, lets see if we can extend our abilities to allow us to put the collection into

an order where the 'Reading_ID' goes from large to small - check the results :-

============================================

So how do we code this ?

Check carefully the details on line 72 below :-

==============================================================================================================

If we want an ascending list we just use the extension method called 'OrderBy' - here seen as part

of the drop list of extension methods :-

======================================================================================================================================================

There are a whole host (lot) of different extension methods for us to use with collections, and we will

improve our knowledge of these as we go along, and make progress within these subsections.

Let move on to something a little different ...........

Indexing with Collections :

Some collections allow us to use and index approach to accessing collection items.

Many of us see this as what we expect in Array use.

Checkout the index syntax for use with our List<T> class :-

=============================================================================================================================

And the result of the above code is seen below :-

=============================

Let us finalise this section by looking at how we could use a 'for loop' to access all items within a collection,

providing it supports indexing ;-)

The 'FOR' loop :

Be careful, don't get too attached to this following method, it is a little dated, or old fashioned - we

just need to know that it can be done.

Study these few but effective code lines below :-

=====================================================================================================

Or if we use an extension method to check the answer we do this :-

============================================================================================

In the image above it is line 84 which does the work for us !

Let us now move on to another subsection.

See you there ..........................

PHH - 30th. March 2013.


some Simple Lambda expression use

some Simple Lambda expression use

some Simple Lambda expression use

 Previous topic Next topic

We do need to know more about Lambda expressions, even if we use the alternative

'standard' code syntax in C# for our LINQ use.

I have found that there are lots of eBooks and references which use the standard Lambda syntax, and

therefore we need to be able to read and use this information - even if we prefer the standard LINQ syntax

which Microsoft encourages us to use.

Here is what the SDK has to say :-

=====================================================================================================================================

And here is another very information section from the MSDN eNotes - study it CAREFULLY !! :-

=====================================================================================================================================

Let us start making our own way through this ...........

We will look at the aspects of Lambda expressions which help us use collections and LINQ generally

in our own projects.

We can apply one Lambda expression after another, in a long line or chain, and these applied in the

order as seen from left to right, reading along the code line. The SDK docs calls this 'right associative'.

Here are two such Lambda expressions - a filter and a sort - check them carefully :-

=========================================================================================================================================================

The results of this code can be seen in the following image of the UI 'DataGrid' control :-

=============================================

Notice above how the 'ReadingID' column goes from small to large, as we move down the column.

Yes, it is the value of the 'Reading_ID' field which is sorted in ascending order - NOT the Value field

which was used for the filter.

But now we can re-order this further, by chaining a third extension method called 'Reverse'.

Checkout the following in full detail - here we use a commonly used screen formatting which makes

it easier to read the individual parts of the compound expression :-

================================================================================================================================

And now at runtime we should see the 'ReadingID' column displayed as 'large through small'.

Check this :-

================================================

Let us now explore some Lambda expressions which do other things for us and our code ..............

Some other Lambda expressions :

Exists :

Let us now try and use a Lambda expression to see if we have a 'Sensor_ID" of 49 anywhere in our collection.

=================================================================================================================

This seems to be correct according to our knowledge of the data, but what if we look for a value of 149 ?

Check this out :-

=============================================================================================================================

Lets move on a see another Lambda expression in action ..........

FindIndex :

Let us say we wish to find the index of the item in the collection which has a sensor ID of 49.

The following code will work for us as we currently have our data - check this out below :-

=======================================================================================================================

And if we remember that the index is zero based, then we can cross-check with the construction

of the collection within our code - see the following detail :-

=======================================================================================================================

Yes, in the above image we see that the 5th item is that for sensor with ID equal to 49.

However, if we add a further item to the collection, and make sure it also has an value for the 'SensorID' column of 49, then

what do we get back as an answer to our Lambda query ?

Check this out below :-

================================================================================================================================================

But what do we get returned if we try to find a non-existent value ?

Checkout carefully the next image detail :-

======================================================================================================================

Yes, as some of us may have expected, we get a value of minus one ( -1 ).

So lets move on to see how to find a whole bunch of items - similar in some way or another ......

FindAll :

Now that we know that in our small data sample above, we have two items with a sensor ID of 49, then

lets see if we can find them both.

Study this code carefully :-

============================================================================================================================

In the above code you can see that we have found and 'extracted' (or copied) the two collection

items into the List<T> called 'allItems'.

We have adopted the common practise of using the 'var' to define our new List (an implied type). However we can see by

hovering the mouse that IntelliSense shows it to be as shown below :-

=========================================================================================================================

Yes, the screen message from IntelliSense tells us that we have a strongly typed List of type 'ReadingNew'.

So we could as easily use an explicit form of C# coding - check the following details :-

=============================================================================================================================

Lets move on .............

Union :

Some of you guys who have done some 'SQL Server' work may be keen to notice that there are 'Set' operations

included in the Extension method list.

As well as Union, see can find Except and Intersect :- checkout the following :-

====================================================================================================

However, we may need to do some mental adjustment, and code adjustment too, if we are to get

these 'Set Operators' to work for us as we may think they ought ;-0)

Let us look at a simple enough test with 'Union' - check this out :-

======================================================================================================================================

You may think that a bit like the SQL script (T-SQL) we can take two lists of items and just 'stick' them

together, but T-SQL has both 'Union' and 'Union All'.

'Union All' did exactly the task of joining together two full sets of items.

On the other hand 'Union' in T-SQL make a final set of items which appear in either of the two given sets, so

they are included only once if the appear in both sets.

This is why in our above test we get exactly the same number of items returned - each appears just once.

We need to investigate this further - lets make a second List of similar items, and give then different values.

Here is the new second set :-

==================================================================================================================================

Because these items are purposefully made to be different to any items in the first set, we should

get a full set of 8 + 4 (or 12) items in the result set.

Check this detail :-

======================================================================================================================================

Well, we do have 12 items which is what we should have expected.

But we really need to find out what they are by displaying the Sensor-ID values of the collection items.

Checkout the following image :-

=====================================================================================

Well, I think you will agree that the last four items are obviously the new ones - those from the second

collection 'List'.

For Set Operators, what is 'the same' ?! :

We need to get things clear in our heads as to when an item in a collection is seen as being 'the same',

or identical, to another item in a second or subsequent collection.

An object (collection item) with similar values (of properties) to another item object, is NOT the same as

the items themselves being 'the same'.

Let us do some tests to show what we mean by all this 'wording'.

Firstly, lets copy the code for two items from List one, into List two - see below :-

=======================================================================================================================

So in the above image lines 59 & 60 are now copied to lines 67 & 68.

Let us build and run the app to see what we get - check this out :-

======================================================================================================================================

The total of 14 means that all of the collection items - from both collections - are seen to be different.

Now then, lets make a change to our code.

Let us make two instances of 'ReadingNew' and then add them to both the first and the second collection.

Here is the code I have on my PC platform :-

==============================================================================================================================

So then, when we build and run with this new code we get a different result - we only get 12 items

in the final collection - see below :-

=====================================================================================================================================

And if we go on to print out these items we see the following on screen :-

=============================

So it would appear as though the final two items in the second collection have been left out of

the final set.

If we make an adjustment to the position of these specified items in collection one we can

prove this to ourselves - CAREFULLY check the following details :-

======================================================================================================================================================

The 51 & 49 at the head of the output list represent items oRN1 and oRN2.

Now lets move on a pace or two .............

'ToList' extension method :

We need to see the 'ToList' extension method in use, and get good at using it, simply because if we are

to pass on the object from our Lambda expression as a parameter, then we need it as a known object type.

Know to our code that is.

This of or particular use with LINQ syntax code, and when we use Anonymous types. We will see more

on this later, for now we will see how to 'ToList'.

Checkout the following image carefully :-

===================================================================================================================================

So the above code shows we are instantiating a typed list and this list can be used in the same method,

as well as being 'returned' from the method.

Let us use it as it is for now - see below :-

========================================================================================

And we can also write this code more explicitly - if that is what you like to see ;-)

Below we replace the implied type syntax with the ex[licit form of code :-

=======================================================================================

However, I suggest you get a little more comfortable with using ' var ' the implied type syntax, as

a lot of eBook material uses it when discussing LINQ topics.

It also serves to shorten and visually simplify the code for LINQ sections of our apps. I have gotten used to

using it where seems suitable, and after a while you get a feel for when to use it and when not. Just make

sure you give it a go, and don't forget that IntelliSense can always come to your rescue.

Now for something a little different, even simpler ...............

'Contains' :

If we wish to know if a collection contains a certain item then we can use the Extension method suitably

named 'Contains'. The result of applying / using this extension method is a Boolean type - so the collection

either contains the specified object or it doesn't.

However, when we supply a custom object we need to realise that this is slightly different to the simple examples

often quoted in books with string types in a simple List, as our collection.

Let us take our current collection as a more commonly seen type of collection. It is made up of objects of type

'ReadingNew' and we have therefore to supply such an object as input parameter to the 'Contains' method.

Look carefully at the following simple example :-

============================================================================================================

This test only proves 'True' because we have previous created the object 'oRN1' as well as adding it to the

collection we have called ''aListRN'.

First of all lets see the code for the instantiation of 'oRN1' - check below :-

=========================================================================================================================================

And now lets see when it was added into our collection - see next image :-

=========================================================================

So this would seem right that the test for 'Contains' turns out to be 'True'.

However, if we now look at a second test as seen below, we get a 'False' result :-

===================================================================================================================

Now here is the interesting part, if we look at the object 'oRNtest' we see that it has identical property

values to those for 'oRN1'.

Study this next image carefully :-

========================================================================================================================================

The reason we got a result of 'False' when we used the 'Contains' extension method was nothing to

do with the property values, it was because the object itself had not been added to the collection in

the first place.

Each 'ReadingNew' object created will have a unique identifier by which the underlying system knows it.

If the object 'identifier' is not seen to be in the collection list of such object identifiers, then it is not contained

in the list and the result is 'False'.

Remember, this has nothing to do with property values, we are discussing custom objects and not simple

value types.

Here is a further test, which really helps to understand what is going on with item collections.

Let us make 'oRNtest' equal to 'oRN1' by assignment - we will not add 'oRNtest' to the collection, but when we

carry out the same 'Contains' test we get a positive result, simply because the system object identifiers for

both oRN1 and oRNtest will be the same.

Checkout thoroughly the following code and runtime output :-

====================================================================================================================================

Now then, there is one further experiment / test we need to do to fully get the feel, or understanding,

for what is happening.

Let us add the newly defined 'oRNtest' object to our collection, as well as the 'oRN1' object - see below :-

======================================================================

And now we will do a test to see how many times the object 'oRN1' appears in our collection.

Check this out carefully :-

======================================================================================================

Our comparison for 'FindAll' was only done with 'oRN1' and yet we get an answer of 2 (two).

So surely this will even convince the sceptics amongst you that the object 'system identifier' is being used.

So be careful with objects and value types, as well as collection comparisons - two separate objects with identical

property values, is not the same thing as two coded variables with the same object system identifier.

Lets move on.

See you in the next subsection .................

PHH - 30th. March 2013.


more on Set Operators

more on Set Operators

more on Set Operators

 Previous topic Next topic

PHH - 31st. March 2013.


'Select'-ing with Lambdas

'Select'-ing with Lambdas

'Select'-ing with Lambdas

 Previous topic Next topic

Choosing with - Select :

The 'Select' extension method is in many ways the MOST important one.

All the data values (property values) which are returned in the query collection come from using

the 'Select' extension method correctly and wisely ;-)

I say 'wisely' as there are a myriad (whole host) of ways to provide the Lambda expression for 'Select'.

Needless to say, some are better than others - as far as being useful in our code once they are used

at runtime.

If we gradually go through some examples, and run a few experiments, then we will quickly get the

idea of what can be done, and what helps us and our code the most.

Let us start be trying to return a collection from our query (LINQ) which is made up of a single item

type - in this case a 'long' or Int64 type.

A single item or property value :

Line 150 is the one which contains the 'Select' extension method - check this out as well as the other

supporting code lines :-

============================================================================================

The above image shows how we can make a collection of items of type 'long' or 'Int64'.

So effectively the collection is one of value types.

However, this is not usually what happens in most application querying - usually we are needing

to select a whole bunch of values for one item of the collection.

In which case these 'bunch' of values need to be 'gathered' together into a single object.

To take the next step in our learning about 'Select' we need to see what happens when we need

to return two data values per item .............

Multiple / Many items or values :

Once again, let us focus particularly on the first line of the code to define our collection made from

a LINQ query - checkout line 162 and then the rest of the code lines :-

============================================================================================================

We can see that there is a fundamental difference between the Lambda expressions for one and two

data items returned.

When we had one data value the return was an object of type that of the data value - i.e. the data type :-

========================================================

However, the syntax for the case when we have more than a single data value shows this below :-

================================================================================

Now then, any guy with a bit of experience with C# coding would say that the above code looks like we

are instantiating an object to be of a class (type) which has not been stated, or typed out - in other words

the class seems to be missing !?

Well, now you know what an 'Anonymous Type' is.

If we hover the mouse over the 'var' in our code when we use the query in a subsequent 'foreach' code

structure we see this below :-

========================================================================================

As you can see from the tooltip sort of message from IntelliSense, this query return was made up from

FOUR separate data value types.

The next image is what code we used to make the anonymous type seen above - check this out carefully :-

===============================================================================================================

[ Whoops ! - line 195 should read 'FOUR' and not 'TWO' .... ]

So effectively, you could say that anonymous types exist to allow us an easy way to write LINQ queries.

So that we don't need to have a 'receiving' class defined in our code.

Believe me it is so much easier - save a lot of basic and fiddly coding - to use the anonymous Type approach

than to think of creating a suitable class for each query made ;-0)

Let us now see the alternative coding - that of the C# declarative approach - study the following thoroughly :-

=================================================================================================================

Now then, before we leave the topic of the use of the 'Select' extension expression, and Lambda methods,

let us see how we may add the use of the 'Distinct' expression to good effect.

Lets go and see how we get a collection returned with NO duplicate items at all ............

Distinct :

As with other places, the use of 'Distinct' varies slightly depending on whether our collection is of custom objects,

or indeed data value types.

Here we will explore the custom type as it is likely to be more commonly used.

Below we have the image of code used to make a collection (List<T>) of eleven (11) items.

However there are only 8 different items as we have added oRN1 twice, and oRNtest is the same as oRN1, so

effectively we have added oRN1 four times, or three time more that a unique entry.

Checkout the following details, and the runtime display too :-

=============================================================================================================================================

So we might ask ourselves, what made our list of 8 items from the 11 original ones ?

Well, the code shown below shows how easy we can use 'Distinct' to do a useful task for us.

Check through this next image, reading the code details CAREFULLY - check line 224 in particular :-

================================================================================================

And for those who don't believe ;-) here is the same data being queried and no 'Distinct' extension

method being applied :-

====================================================================================================

We can clearly see the three 'extra' items at the top of the list - these are three duplicates.

At the moment I am unable to get the 'Distinct' method accessed by declarative code.

I need to explore this more.

Oh! I have come up with something useful - its a start at least - check this out below :-

===================================================

If we use ' query.Distinct() ' then only unique items are included as the resulting collection.

Here is some code which uses this to good effect :-

=======================================================================================================================================================

In the above code it is line 248 which gives us the Unique items sub-collection to work with.

However, we can also do a similar thing earlier in our code, at the query end of things.

What we see in the following image is that we need to get the syntax correct, as far as round

brackets are concerned - notice lines 235 and the start of 244 :-

=============================================

So if we now use the 'Distinct' method at the query, and remove it from the 'foreach' condition, we get

the following code and runtime display :-

================================================================================================================

The result in the display within the message box is the same - BUT - the query itself is now shorter, and

contains only unique items - for custom objects this means one entry of the object system identifier.

Okay then guys, time to leave things at that for now.

Lets move on ...........

PHH - 1st. April 2013.


some Personal experiences

some Personal experiences

some Personal experiences

Previous topic Next topic

PHH - 30th. March 2013.


some Simple LINQ code syntax use

some Simple LINQ code syntax use

some Simple LINQ code syntax use

 Previous topic Next topic

Okay then guys.

Now that I have justified my reasons for using LINQ query syntax, I will use this section to

show a few different examples from LINQ to objects as well as LINQ to SQL.

Will will also look at making and returning custom class collections, when the first 'Select' clause

was returning an anonymous type as the collection items.

PHH - 31st. March 2013.


Namespace - System.Collections

Namespace - System.Collections

Namespace - System.Collections

 Previous topic Next topic

==============================================================================================================================================

PHH - 30th. March 2013.


Common used - Collection Types

Common used - Collection Types

Common used - Collection Types

 Previous topic Next topic

=====================================================================================================================================

=================================================================================================================================

PHH - 30th. March 2013.


Using a 'FOR' loop and indexing

Using a 'FOR' loop and indexing

Using a 'FOR' loop and indexing

 Previous topic Next topic

Okay guys, here is some working but old fashioned code.

For many of us the 'FOR' loop is a thing of the past when using modern techniques in .NET coding.

However, we do all need to know how to do it, AND, the collection, or array type object, on which we

working needs to support indexing.

Not all collections do this so beware !!

Let us look at a simple example which does work - check this out below :-

===============================================================================================================================================

This sort of code will be VERY familiar to guys coming from Visual Objects (VO).

However, I would suggest that you move over to using 'FOREACH' as some as you possible can.

Also I suggest you try to leave behind you the indexing way of trying to do everything. I rarely need to

using indexing when coding in modern .NET projects.

Lets move on a pace .....

What can we Index ? :

Okay then guys, what can we index ? This is simple enough question but apparently not all collections has indexing

capabilities.

However, I can show you below that the important 'ObservableCollection<T>' does allow its use - see below :-

==============================================================================================================

I suppose it would be good to know which collection types do not support indexing - I will try to find out.

Lets move on ...........

Personal Experience and Comment :

It is my own personal experience with .NET projects - going back a few years - that most of the needs of any

developer, coding standard business type applications, can be met by using List<T> and ObservableCollection<T>.

I would also go further with my comments and suggest that you give up using Array and ArrayList whenever possible.

There are times when these older forms are lacking in some useful feature or another.

Do PLEASE notice that an 'ObservableCollection' (OC) object can be instantiated from a List<T>, as see above.

See more on OC in the section a few on from here in the eNotes.

PHH - 5th. April 2013.


Using an Enumerator

Using an Enumerator

Using an Enumerator

 Previous topic Next topic

Okay guys, I am not sure why I am doing this little subsection, apart from learning the hard way

to move through a collection, an item at a time, and read or process it (the item in focus) in some way.

When we iterate through a collection using an Enumerator we say the item in focus is the 'Current' item.

We also see from the IntelliSense drop list options (see below) that this is a 'forward only' process.

There is a method on offer to move to the 'next' but not the 'previous'. Check out the following :-

==============================================================================================

So what we need to do is try out a few coded experiments, just to see how things work for us.

Let us make ourselves a good example in code, with some real life data.

In the next image we see that a bunch of 'RaedingNew' objects are instantiated and added to the List<T> collection :-

=============================================================================================================================

So our collection above, is a typed list of 'ReadingNew' objects, and it has a variable name of 'aListRN' - this

name is all my own choice and has nothing to do with the underlying system.

Now we need to see how we define an Enumerator - we can do it the easy way, or the knowledgeable way !?

here is some code which works okay :-

===========================================================================================

We can also see below how IntelliSense offers a whole bunch of methods and the odd property for our collection.

I have chosen the obvious one for now - 'GetEnumerator' - see below :-

================================================================================================================

Also, while we are at it, we may as well see how IntelliSense shows us what type of class the ' var ' is.

Check this out in the next image :-

===========================================================================================================

Personally, I have no problems with using ' var ' in a suitable manner, for times like this, and for LINQ stuff too.

We see many web and News Group comments about it being 'bad practice' and / or over used.

However, after much LINQ research I find it quite acceptable in the right place - AND - it clears and cleans our

more complex code a 'tad' (little bit).

Here below is some working code for us to build upon - check it out :-

==================================================================================================================

As you can see we need to use our own 'FOR' loop if we are to use the Enumerator directly.

Lets make a change and improve this code by using a 'WHILE' statement :-

====================================================================================================================

Yep! above we get the same results, but our code is a little simpler and cleaner.

But, if we now move on to the 'FOREACH' statement it becomes even simpler, and cleaner - see below :-

=================================================================================================================

Finally, we need to see that from the enumeration process we can change any of the property values of the collection

items, just not alter the collection itself - here we change the value of all 'Reading_ID' values :-

===================================================================================================================================

So all of out collection elements (or items) remain intact, but their values have been change on

one of them - the 'Reading_ID' property.

Lets move on a pace ..............

When to Stop Enumeration !? :

Okay then guys, we have said and shown how we can step through our collection an item at a time BUT we

don't have to go all the way through if we so wish.

Here is a rather contrived example of how we can do a test and if the test condition is met, stop the enumeration,

or effectively step out of the 'loop' structure - check this out :-

================================================================================================================================

Yep! using 'BREAK' gets us out of the enumeration process.

Now we need to look at when we just wish to 'skip' a single step of the process, while allowing the enumeration

to proceed.

When to Skip during Enumeration :

Okay then, breaking out of the loop is one thing, and stops the iterative / enumeration process,

but what if we just wish to miss out on the current process, and skip on to the next item in the collection ?

Well, that is also quite easy to do, we need to use 'CONTINUE' after a conditional test. The conditional test

is generally before any processing code.

We can slightly change the earlier code, to test for even valued Reading_IDs and then skip these.

If this code below is correct them we should be able to list only the odd valued collection items.

Odd in respect of their value for the property called 'Reading_ID' - check this out below :-

============================================================================================

And when we build and run we get this :-

===================================================

Yep! that looks right to me, so 'continue' is skipping for us and our code.

Time to move on .......................

See you in the next subsection.

PHH - 3rd. / 4th. April 2013.


Using 'foreach'

Using 'foreach'

Using 'foreach'

 Previous topic Next topic

Okay folks, so far you have seen the 'foreach' "loop" in use with our collection and query

samples, and now it is time to delve a little more deeply.

Some of us refer to the 'foreach' as a 'loop' and some as a 'code structure'.

Basically the 'foreach' replaces the need for us to write FOR loops in the conventional way, when

dealing with Arrays and Collections.

As well as behaving like the FOR 'loop' it also provides us with the enumerator - an important part

of the collection class functionality.

Let us start by seeing what the MSDN eNotes have to say - check this out below :-

==================================================================================================================================

Okay then folks, the above information is helpful to get us on our way BUT it does not say everything in detail that

we need to know, or possibly as clearly as we require.

Let us see an example of some of my real life "Data Logger" application - check out this carefully :-

===============================================================================================

Although the above code is necessarily 'awkward' and needs MANY ' if ' statements, we can speed up the

data correction process by 50% by using 'continue' as soon as one condition has been found to be TRUE.

The 'continue' statement sends processing back to the top of the loop, for the next iteration to start.

On average my code will not visit half of the 'if' statements - this was not worth trying to improve as it

was a one-off data correction operation, and simplicity was more important than speed.

Lets see what Ian Griffiths - author of "Programming C# 5.0" has to say :-

========================================================================================================================

The above paragraph was written for WHILE loops but as it mentions in the last sentence, it applies to

all the 'looping' code structures.

Lets move on ..........

What can we do with the Elements Provided by the Iteration ? :

Okay then, we need to get a few things into our heads about the 'iterator' or 'enumerator' which provides the functionality

of the ' foreach ' loop.

As mentioned above we can't add to or remove from the collection itself. So the list of items has to contain the same

elements or members for the whole operation of the iteration / enumeration process.

So if we can't Add or Delete, can we change and alter data within the collection item 'in focus' ?

When an item in the collection / array is the one being 'pointed at', or said to be 'in focus', then we may

use the data values of the objects properties, as well as change then - we just can't remove the object itself.

We will see MANY examples of items being changed throughout these eNotes, and have probably seen quite a

few already while reading earlier sections.

Where does LINQ fit in ? :

The following MSDN eNotes suggests that we do our list / collection processing via LINQ and not 'foreach' :-

====================================================================================================================

PHH - 30th. March 2013.


System.Linq - namespace

System.Linq - namespace

System.Linq - namespace

 Previous topic Next topic

===============================================================================================================================================

=============================================================================================================================================

===============================================================================================================================================

PHH - 30th. March 2013.


some Simple LINQ code

some Simple LINQ code

some Simple LINQ code

 Previous topic Next topic

I will assume when I write this subsection that you the reader know very little about LINQ querying.

For us to write C# code for a LINQ query we must write it against a collection, and this collection

is either already in memory or is made from data on disk in a data source like SQL Server.

LINQ to Objects is RAM based in its collections, and LINQ to SQL get them from defined tables.

LINQ to SQL is only for use with Microsoft SQL Server, and tables can be addressed (or queried)

only singly - one at a time, or one per collection specification.

Let us now see a simple example of a 'LINQ to Objects' query, and then discuss it later.

Check this out :-

====================================================================================================================

Most of this is quite intuitive and you soon get good with it and its possible variations.

However, I have to say that I found the most difficult part to get my head into and around,

was the 'select' clause.

Selection can be tricky if you are not fully aware of what needs to be coded.

For now, lets make the query a bit more complex - note below we can have multiple 'where' clauses :-

=====================================================================================================================

In the above query (our second simple one) we are still selecting the whole of the original collection item.

Code line 419 effectively chooses the item from the original collection, and although we use properties of the

chosen item for filtering and sorting, we still include the whole of this item in the return collection.

The returned collection is that collection made up from the whole or part of the original collection.

At this point we had better cross-check that we actually know the format of the object 'aListRN' object - see below :-

=====================================================================================================================================

Now then, lets venture into the topic area where we choose to select only some of the

original property values for the return item and hen collection.

In the example below we will specify the property values we require, but NOT the type of the class

of object in the returned collection.

When we do it this way we say we are using an 'Anonymous' type.

Checkout the following image details to see we are placing three values in our Anonymous type :-

[ .. check out line 423 .. ]

=======================================================================================================================================================

Notice that having an anonymous type in our returned collection does not stop us processing the

collection further - here in a 'foreach' structure.

However, things will get difficult for us if we wish to pass on this returned collection - as say

an output from a Method we define.

To return a collection of Typed objects from a method is seems that we must make it a Custom type.

Let us look at a simple Custom type of my making - see below :-

========================================================

So then, now we have a Custom type defined, we can use it with our 'select' clause.

Study the following details, in particular lines 423 to 429 :-

=====================================================================================================================================

In the above image we see that there seems to be a "one to one" correspondence in the property names.

However, in reality we only have to assign the correct value types to the left hand side property names.

In the next image we can see where I have played around with the property values from the original collection items.

And seen below in line 426, we see something quite silly or absurd, but it still works as the values are possible ones :-

========================================================================================================================

So as the above code demonstrates, the 'select' clause is all about the LHS being correct and suitable fields

(or columns) and the RHS of the assignments are all about the correct data type being specified.

So the calculated field of value plus sensor identity is acceptable to the compiler.

Normal Assignments in 'select' :

Although we needed to show above that many things were possible within the select clause, and needed to

show something 'silly' to make a point, we would normally match up the fields on a one to one basis.

Usually, when we define a new Custom class for ourselves to use with 'select' we are making a class around

a reduced set of fields from the item objects in the original collection.

The only change to what is said above, is when we are joining fields from more than one original collection.

Let us move on a pace to see some simple code for both 'joining' and 'selecting'.

Joining - extracting property data from items in more than one collection :

Okay then guys, if we are to use more than one collection as our source of data values, it is probably much

easily for me to use those collections which originate in SQL tables.

Below I will use the tables 'ReadingNew' and also 'DumpSetHeaderPlusX'. We will see a little later what the C#

code looks like for the corresponding defined classes.

For now just see how easy it is for us to create two collections - RNs and also DSHPXs - see below :-

=====================================================================================================

In order for our code to compile we need a couple of lines of 'using' statements to add suitable namespaces.

Checkout below what is required :-

===============================================

And finally, before we study the LINQ query code, let us see three necessary local variables and their specified

values - just a couple of dates and a sensor identity :-

==========================================================

So now we can focus on the task of making one returned collection from two original collections.

Checkout carefully this code shown below :-

===============================================================================================================================

Since the original collections are filled with different classes of item, we really need to see what these classes

look like - or the fields on which they are based.

Below I have shown how the tables look in Management Studio :-

=========================================================================================================

And when we convert these into C# coded classes, they do get a bit more complex, simply because we

need to add attributes to allow the underlying system to relate these classes to the SQL tables, as part

of what LINQ does for us in "LINQ to SQL".

Study the following properties and the constructor - first for the 'ReadingNew' class :-

[ .. sorry this looks so complex - it is much simpler than it looks ! .. ]

======================================================================================================================================

And now we have a slightly longer class for 'DumpSetHeaderPlusX' :-

[ .. once agin the following is MUCH simpler than it looks .. ]

=============================================================================================================================================

Now before we study in depth the query above (before the class definitions) we need to see the

simplest possible way to 'select' from our two original (or input) collections.

Below we will make one returned collection from our two input ones.

Check this over carefully :-

=============================================================================================

Although the details in the message box look complicated, in fact all they tell us is that we have

an output (or returned) collection which is made up from items of an Anonymous type.

It also says that the anonymous type has two properties, one of value a 'ReadingNew' object, and

the other property with a value of a 'DumpSetHeaderPlusX' object.

Although this is simple, we usually wish to have the items in the returned collection to be data types

whenever possible, or when it makes good sense.

I have now gone back to our original code for joining the two collections based on the SQL tables.

Checkout this slightly altered code and then compare the output results below the next image :-

============================================================================================================================

With the sensor ID set at 29 and the new date range, we get the following results :-

[ .. note that line 452 binds the returned collection to the WPF form's data grid element .. ]

===================================================

Okay then, we have three data values in the above data grid, so what if we wish to return more ?

Well, look at the next output display, as we have a few more shown here :-

========================================================================================

All that we have needed to do is to add further properties to the 'select' clause, specifying a

property name (all mine start with 'my') and make a suitable choice from 'd' or 'r'.

Of course we could also have more collections to join with - I suggest you look at an example

from my current real life 'Data Logger' application : - see below for some ideas :-

=================================================================================================================

In the above code we have something interesting taking place. We are specifying a few joins using the same original

collection.

Notice that every time we specify a join we define a condition for joining ' on a8.DumpSet_ID equals a9.DumpSet_ID'

and also a filter to choose only those fields we require.

I think you may need to study this code, and then try some of your own, before you get really comfortable with what

is actually taking place.

This syntax is different to that which you may have previously used in SQL Server scripting.

You may also have noticed that I used the results of one LINQ query as a collection in the RHS of the

definition of another query. This is a technique we will look at more closely later - possibly in the next

subsection.

Lets move on ..................

See you in the next section.

PHH - 30th. March // 5th & 6th April 2013.


some 'Standard' multi Joins

some 'Standard' multi Joins

some 'Standard' multi Joins

 Previous topic Next topic

For those of us who do not quite get their heads around self-joins, or using the same collection

more than once in successive 'join' clauses, I will show you a 'standard' and somewhat classic

example of using many joins in one query.

The classic case I mention above is the Customer, Orders, OrderItem, Product, ProductType sort

of 'progression' - where one table ID points to the next.

Let us see a demo / test database of mine in my SQL Server and Management Studio set-up.

Check this out below :-

===================================================

And if we take a quick look at the SQL script (written in T-SQL, or Transact SQL), we see this

which works and supplies us with expected results - check below :-

====================================================================================

And here are some of the result rows / records - I have had to section these results simply because the grid was so wide :-

============================================================================================================

=======================================================================================================================================

===================================================================================================================================

As you can see there are 25 fields or columns.

And the next part squeezed or collapsed view show the totals number of rows found - see below :-

Okay then guys, how do we do this with LINQ code ?

What do we have to do to make a similar set of joins using LINQ and a collection for each

of these tables ?

line 533 through 540 are simply to make collections from SQL tables, the C# code from then on is

general code, and the same approach can be used for in-memory objects, wherever they originate.

Let us take a CAREFUL look at the code to make four joins using five different collections.

Check this out thoroughly :-

======================================================================================================

[ .. note to use 'equals' and NOT '==' for the join conditions .. ]

Well, we at least get 31 rows, the same as with a T-SQL query in Management Studio.

However, the code line 548 produces an output (or returned) collection which is not ideal for us.

I used line 548 because it was short, and did not confuse the rest of the code, so we could see clearly what was happening

with the 'joins'.

With the 'select' clause unchanged we see the following in our 'DataGrid' WPF control :-

===============================================================================================================================

We really would like to have data type fields, and so we need a more detailed and complex

specification of what we need to 'select'.

This is quite easy to do, once we know what is expected in the C# code. Note below that we

can't duplicate fields in an anonymous type, when we are not specifying the field or column names.

Checkout the following carefully:-

==================================================================================

And now you know about no duplications check out the full 'Select' clause which works nicely for me here :-

======================================================================================

So what does the runtime display look like at a WPF form level ?

Well, we have a lot of columns so if I show you all in one image we will not be able to read it very easily !

Checkout the following interesting image :-

============================================================================================================================================

And to show you I am not cheating, here is the top LHS of the full grid :-

====================================================================================================================================

However, we can now revisit our earlier problem of wishing to include ID field values from different collections,

but which also had the same names.

If we make sure that we provide our own unique filed names (these end up as property names in an anonymous type)

then we can actually get this to work for us.

Se my changes below :-

======================================================================================================

This now means that the default names created by the system for the anonymous type as well as the four

provided by me, do not have any name 'clashes'.

See the following new 'DataGrid' this new code makes - I have collapsed may fields by left the new ones whole :-

========================================================================================================================================================

And finally, we can tidy things up by removing fields which we don't really need, and this then

makes a narrower and more acceptable grid display - as you can see shown below :-

=====================================================================================================================================

Obviously, we would like to see the edited code which produces this nicer grid display, so

checkout the details shown in the next image :-

================================================================================================

There you are, as simple as that - once you know how ;-0)

And we have learned a few useful tips and tricks on the way.

Time to move on - see you in the next section ......................

PHH - 7th. April 2013.


chaining LINQ queries - Groups

chaining LINQ queries - Groups

chaining LINQ queries - Groups

Previous topic Next topic

In some ways this small section should not be necessary, however, I found that when I came to

coding in LINQ it did not come to me that I could 'chain' query variables.

Let me explain. At first when many of us come to using LINQ, we do not appreciate from the outset

that a 'query' is a returned collection. And as a collection can therefore be used in the RHS side of the

code for a further query.

By convention we tend to use 'query' as the name of the collection which is returned from a bunch of

LINQ C# code. But in fact we could call it anything we like, as long as it conforms to the rest of the C#

naming conventions.

Let me explain further.

If I edit the code in a simple query to join two collections and select only a few data fields, we could

have something like the following :-

==========================================================================================================

In the above code the name 'query' has been replaced by 'ourResultCollection_01'.

The fact that we have such a name for the returned data from our coded query, reminds us that we

have in fact got a 'collection' object.

We can shorten this to be something less unwieldy - see below :-

=========================================================================================

Now the point of all this is that if what we are creating is just another collection, then in fact it is VERY obvious to

us all that we can then use it as a collection object on the RHS of a further 'query' definition - or specification.

Once we know this then there is no need to hide the fact, and using 'query' and 'query2' etc., is probably

more use that renaming each one to disguise the fact that it was made as a result of a LINQ query.

The reason I got to using multiple, or chained, queries was that I found it easier to design and write LINQ

query statements which did as I required.

One particular scenario is when we wish to make groups - or carry out grouping of data rows - or should

we say collection item properties ?!

Here is a good example of this, from a working real life application - the "Data Logger" :-

=====================================================================================================================

The above image shows code which produces the following data grid display at runtime :-

===========================================================

Now then, this all seems very nice, and easy enough too - BUT - we need to remember that

the query2 actual 'SELECT' statement which is scripted for the underlying ADO.NET code is only

done when the data for it is required, so when we use 'query2' the LINQ system creates a compound

SQL query from the specification of query and query2 in order to send one SQL query statement to

the SQL Server.

Lets us look first at the compound query which generates our grouped data :-

====================================================================================

You should find that this is built from both 'query' and 'query2', and is found by simply a

code line as shown in the image below :-

========================================================================

Now then, there is no reason at all that we should not try and display the SQL statement

generated for 'query' on its own - here it is shown in the next image :-

===================================================================================

And similarly to that previous message box display, we do the following in our code :-

==========================================================================

Don't get misled by the size of the query text, or its apparent length, this first query shown above,

is in fact included with that which we saw earlier in this section.

Lets move on to discuss the 'Grouping', and ways to achieve what we wish in a group clause.

Discussion of the Grouping :

The trick with 'grouping' is to first assemble a suitable collection object, one which then allows a simpler

coded syntax to be used, to achieve the grouping we are after.

I found that when I first came to LINQ I tried to do too much in one query, and got confused as well as

very often failing in what I was trying to create and produce.

Let us isolate the code lines which do the grouping, so that we can discuss them in suitable detail.

Here are the lines to study :-

====================================================================================================================

And just to get our heads into this, lets take a look at the real life output created

from the code we are studying :-

================================================================

Okay then folks, before we can concentrate on the grouped collection we need to

know exactly what we have in the collection specified by 'query' - the outcome of our

first LINQ query code.

Take a look at the collection items which make up part of the 'query' collection :-

=======================================================

The difference in the 'Tag' does not matter, it the general nature of the other data

which does matter.

As you can see we have many rows with the same 'myDate' value, and the temperature value

called 'myValue' varies slightly from one reading to the next, 15 minutes later.

Now we can study the two lines which define and sort what is the equivalent of a 'holding collection'.

In the following code the 'g' represents this 'holding' collection - check this out :-

==================================================================

So the two data values, from the 'query' collection, which determine which rows are grouped,

are seen in the 'group selection' seen in line 512. Here we have an anonymous type which is used

to specify the group collection.

Once we have our grouped holding collection we can then use it to 'select' the return collection from

the query2 LINQ code.

When we use 'g' there is only one property we can use to get at the data vales, and that is 'Key'.

Look at what IntelliSense has to say :-

==============================================================================================================

Basically, this means apart from the 'count' method on the whole grouped collection, we need to use 'Key' as

shown below to get at the field / column values. Actually these are property data values of the anonymous type.

See below how we get at 'myDate' and 'myTag' values

===============================================================================================================

In the above image pay particular attention to line 518 which shows us how to make an aggregate value,

in this case an average.

Yep! the Average() method is an extension method taking a Lambda expression - so it is important to know

how to use them, and how to construct a Lambda expression as well.

You will notice above that we are making a final returned collection with items of class 'SingleSensorAvg'.

So in that case we need to know what this class looks like - here it is, study it thoroughly :-

=================================================================

Lets make a summary ..............

Summary :

Don't be afraid to use chained LINQ queries - they work fine and help simplify the tasks in hand.

If you are doing 'grouping' separate the group specification on a collection which is already suitably

formed (made) by first using a previous LINQ query.

It helps to be able to use custom classes in place of anonymous types (AT), but if you do use 'AT's

then remember that default duplicate field names can't be used for property names - code them as

unique, by hand and hard coding.

Enough of all this progress, lets move on to the next subsection.

See you there ......................

PHH - 6th. April 2013.


ObservableCollection<T> class

ObservableCollection<T> class

ObservableCollection<T> class

 Previous topic Next topic

Hi guys, so why do we have or need the 'ObservableCollection<T>' (OC) class ?

If we instantiate an 'OC' directly form a List<T> as shown below, then why don't we just use the

actual List<T> itself - check this out :-

=======================================================================================================================

Well, its all about Data Binding, GUI display, and seeing any changes made to the collection within the UI controls

to which the collection is bound.

The OC class has suitable event notification for items being added to, and removed from, the actual collection.

It also seems to correctly handle (and respond to) the notification for the individual items, with respect to any

'INotifyPropertChanged' events coded by developers into the custom class of the items.

Remember, any Dependency object we make needs to respond to changes in any of its properties by firing the

event related to 'INotifyPropertChanged'. This is part of defining a Dependency Property and a Dependency class.

If you are not familiar with all this then visit the Appendix E section.

Summary of Event Responses :

The OC handles the event notification of collection changes with respect to items themselves.

The item class handles the event notification of changes to the properties of the items (objects)

themselves.

Under certain situations, the OC will pick-up and react to property changes when they effect the display

within the UI control of the bound OC - usually to do with sorts and filter conditions related to specific

item properties.

So if a control is bound to an OC which is sorted by order of 'Name' (one of the item properties) and the

name of an item is changed (either in code or by the UI), then changes will be reflected in the sort order

within the UI element.

From my personal experience, the ObservableCollection<T> is our friend - we need to learn how to use it.

Now then, lets have a look at what the SDK docs have to tell us about 'OC's :-

===================================================================================================================================

In the above image it is the third overload of the constructor that I commonly use in my code.

Instantiating from a typed list (List<T>) :

Note that to use the OC class in our code we need to add the following 'using' statement at the head of our code files :-

========================================================

Line 28 in the above image is what is required - note the highlighting :-

Now let us study the code, and runtime display from a simple example on mine :-

==========================================================================================================================

For the code section shown above, we do not actually need line 148, as the 'foreach' structure handles

the loop control - we don't need a count or a maximum value.

Before we look at OC in GUI controls, lets get to grip with all the basic stuff first.

Lets look at another overload in use - lets use a Type and then add items to our collection.

Instantiating with a Type :

So as we do not try too many new things in one go, let us use the 'ReadingNew' class we have used many times

previously - in earlier subsections.

Checkout below line 160 and the next few lines too :-

=============================================================================================================================================================

The approach taken above would tend to indicate that OCs can also have their items accessed using an index.

Let us try this out now - see the following image :-

========================================================================================================

Yep! we can certainly use indexing syntax to get at values within the 'OC'.

Let us now see what we can do with returned query collections - anonymous types and all that stuff ;-)

Instantiating from 'IEnumerable' :

We can get his first overload of the constructor to work for us - BUT - we need to be very careful

how we code the query (IEnumerable) which we use in the instantiation.

Our biggest problems come when we code such that we get a collection of anonymous type.

When this happens there seems to be no way to specify the type in our code for instantiation.

CARE !! - problems with using Anonymous types - see below :-

=======================================================================================================

The IntelliSense shows us what the type is - check this out :-

==============================================================================================

But I can't find a way to code it.

It seems better to me if we create a suitable class which can be used to accept the LINQ query data values.

Look at the following image to see what seems to work quite nicely :-

========================================================================================================================

However, the collection created still is of type 'IEnumerable<T>', but now T is our custom 'ReadingNew' class.

Check these details :-

===========================================================================================================================

So to summarise, if we are going to make an 'OC' from a query, then code the query to use a

specific class defined by your own code. This allows us to then specify 'T' in the generic chevrons.

There may be other more complex ways around this - BUT - why bother ? Keep it simple I suggest.

Lets move on to see some use of the methods used to operate on the collection of items, once

we have instantiated an OC.

Add / Remove :

PHH - 30th. March / 5th. April 2013.


Complex querying - some tips and tricks

Complex querying - some tips and tricks

Complex querying - some tips and tricks

 Previous topic Next topic

PHH - 1st. April 2013.


Chapter 2 -

ClickStartLINQ

Chapter 2 - different Syntax Styles

Chapter 2 - different Syntax Styles

 Previous topic Next topic

Chapter 2 - different Syntax Styles

 Previous topic Next topic

PHH - 11th. August 2012.


'query expression'

'query expression'

'query expression'

Previous topic Next topic

PHH - 11th. August 2012.


'Lambda method'

ClickStartLINQ

'Lambda Methods - Operators'

'Lambda Methods - Operators'

 Previous topic Next topic

'Lambda Methods - Operators'

 Previous topic Next topic

PHH - 11th. August 2012.


Chapter 3 -

ClickStartLINQ

Chapter 3 - METRO with C#

Chapter 3 - METRO with C#

 Previous topic Next topic

Chapter 3 - METRO with C#

 Previous topic Next topic

PHH - 11th. August 2012.


In-Memory Collections

In-Memory Collections

In-Memory Collections

 Previous topic Next topic

PHH - 11th. August 2012.


Chapter 4 -

ClickStartLINQ

Chapter 4 - 'Query' - the Clauses (QE)

Chapter 4 - 'Query' - the Clauses (QE)

 Previous topic Next topic

Chapter 4 - 'Query' - the Clauses (QE)

 Previous topic Next topic

There is sufficient detail in the subsections of this chapter to help and guide you with the structure of the

QE itself, and how to craft your own query expressions.

However, it is important to use this short section to guide your learning if you are somewhat new to QE and

even SQL query statements themselves.

Very often in books we see the authors covering all of the aspects of a topic, and giving us working details

of each and every part of all topic areas - BUT - most often the 'new guy' needs some definite help, and with

some specific pointers.

Well, this is what I intend to do here ;-)

Until you get going and can make your own QEs and get the results you expect, forget trying to use 'Group'.

In fact if I were you I would also leave 'Join' till you are comfortable with querying a single collection source.

Focus on "From, Where, Orderby, and Select", and get good with these.

Probably most folks QEs are based on these clauses, and make sure you are good enough to write quite

complex clause syntax for Where and Orderby, as multiple conditions for these are VERY commonly required.

This is another area in which text books (and SDK notes from Microsoft) often fails us 'learning' guys.

We need to be able to make multiple condition sub-clauses for 'Where' and 'Orderby', so look out for these.

I am not too sure as yet how important or commonly used will be the 'Join', but if it is anything like SQL querying

then once you can handle it you will be using it most, or all, of the time!

And with 'Join'ing there is an easier way and also more complex ways. When you first go to using 'Join' just

stick with the 'inner join' which returns a 'flat result'.

The 'Left Outer Join' is easy enough to use and get the syntax right - BUT - it is more complex to understand

just what is going on if you are new to SQL and joining in general.

So a step at a time with joins and joining - then you will get good results and NOT frustration.

However, Grouping is something which can be left till later, and when we get around to examining it in fuller

detail we can decide how and when to use and apply it.

I now suggest we get going, and look at the overall 'Anatomy' of the query expression.

See you in the next subsection ...................

PHH - 13th. August 2012.


Anatomy of the 'Query'

Anatomy of the 'Query'

Anatomy of the 'Query'

 Previous topic Next topic

Don't panic if this title seems a bit 'serious' ;-)

In fact this small section is about how the overall query expression (QE) 'looks'.

In which order can we place the separate 'clauses'.

Which clauses are optional and which MUST be present.

So 'Anatomy' refers to the overall 'shape' and form of the query.

Note that we need to address the same issue when using Lambda 'method' Operators.

The Most Obvious :

I write these eNotes on LINQ as an experienced guy with .NET use, and also a few years of involvement

writing SQL statements to use directly with Management Studio, as well as ADO.NET.

So I can't help comparing everything in LINQ technology from Microsoft, with their SQL Server syntax.

With this in mind I need to say that with SQL Server syntax the user has to learn to 'read' the query

statement - as Paul Nielsen explains.

To shorten his words and statements etc. - 'SELECT' is basically in the wrong place, and we should start

to read our query statement at the 'FROM' clause.

Well, it would appear that this has now been corrected with LINQ - the 'select' clause comes last, as it is

the one which 'determines the shape of the query output'.

To start to understand a little more look at the following image :-

========================================================================================================================

In the above image we see that in a pretty standard query expression I have tried to remove the 'select' clause.

The on-screen tip tells us a lot.

The query expression MUST end with either a 'select' of 'group' clause.

So lets say that for most query expressions they end with a 'select' clause.

Also, as for Paul Nielsen's good advice, the first part of our expression says where we are going to place our

results data - the data returned by the query itself. Or, if you prefer, what object into which you are going to put the

returned data - the results.

The next part is from where we actually get the possible data items - so the 'from' clause comes after we know where

the results are going.

I don't think there is anything wrong with thinking of the returned data 'set' as 'results'.

So basically, our results are a bunch of objects - singular or multiple.

Each object with have properties determined by the 'select' clause - as this determines the 'shape' of the output object.

So here is a generalized overall 'shape' of most common queries - the [ ] signal optional.

Note that the order of these clauses is important, and must be adhered to :-

- output object

- 'from'

- ['join']

- ['where']

- ['orderby']

- ['group']

- ['select']

And yes, we can have both optional clauses 'group' and 'select' - see below :-

========================================================

Lets move on a pace or two ...........

The Most Fundamental QE :

Okay then, it may help to see what the most basic or fundamental query is that we can design and test.

First checkout the code as seen below :-

======================================

Well, I told you it was basic ;-)

The query reads as ..... " into the object to be called 'result', place the data from the collection object called

'oCusts' and place each object in the 'result' object as it is (as-is) - don't restrict any existing properties. "

And by now you realise that I like to work 'live' as I write my eNotes, and that I am actually trying and testing

this C# code within a METRO application as I am going along.

So in that case see what came out from the data I have in my app STATIC method at the moment.

Check this out below :-

============================

*** CARE *** please be warned NOT to read the graphical output as the properties on our results objects. In fact

those properties displayed are determined by the template we apply, and the ToString() method on our selected

class - quite a few things.

So just take the above as an indication that our VERY simplest of query expressions (QE) does in fact work, and

that it produces for us what we may expect.

Let's not be lazy ! :

Oh! we must NOT be lazy, and also realise that the whole point of writing these eNotes is to learn 'stuff'.

So let us take this opportunity to write a new DataTemplate for our ListBox control.

And as usual, let us have a peak at success before we study the details of how to do it all - see below :-

==============================================

Okay then, that looks better, at least we can see that we have all the properties of the Customer class object,

being passed through to the 'select' clause and the result object.

So now we need to view the XAML script for applying the new template - check this out below :-

==========================================================================================================

As you can see in the above image, the script line 84 is associating the 'ItemTemplate' attribute with the

'StaticResource' called 'CustFullDatTemp'.

However, as we are also learning something about XAML as we go, we also need to see that we have an alternative

'short hand' syntax which allows us to drop the 'ResourceKey=' as you can see below :-

==================================================================================================

Personally, I am not in favour of such short-cuts but we need to read other guys script, so we need to know what

is possible and what can be done by others.

Here is proof once again that this works - obviously I compiled and ran after the above image was captured, hence

the yellow LHS marker turned to green ;-)

Notice in the following live image that the second list item is highlighted in grey :-

===========================================

And now we had better see just what the actual template looks like. Notice the 'Width' settings of 'Auto' :-

====================================================================================================

Don't forget that data templates are VERY flexible and powerful, and we could just as easy have included

a photo image of the customer as well.

Providing an image via the template can be useful for product and stock items as well, in much the way

Amazon and other eStores do.

Query Anatomy - to Summarize :

Although we can make some generalisations and set out a few guidelines, by the very nature of the QE

it is, and has to be, VERY flexible, and therefore can vary in details a GREAT deal !!

So yes, I am going to say that the ONLY definite way to become 'master' of the QE is to look at the QE's

of others, and to copy and adapt them for your own needs. And yes, once again, I will say what you may

not wish to hear - there is no easy and quick way to become a 'master', but by lots of experience in varied

situations, you will gradually get a good feel for all this QE stuff.

Just like I had to when learning to query with SQL statements.

However, the good news is that this is NOT a complex topic, nothing like rocket science, and there is also

a wealth of useful material out there to help.

Time to move on ...... see you in the next section ..............

PHH - 13th. August 2012.

Addendum :

While we have the application running with the DataTemplate for the full Customer class, it is too good an

opportunity to miss out on showing what happens when we restrict our output object to less (or different)

properties to those in the original (or source) collection.

Let us change the VERY simple query expression just a small amount then check the output visually.

Below is shown our altered QE syntax - check it out :-

=======================================================================

So what do we get in our list box when we run this slightly changed code ?

Study the following image carefully, and make some deductions :-

=================================

Yes, we appear to have just two properties so the 'binding' of non-existent properties to the other

TextBlock controls will just not happen

Remember that a 'binding' to a Path which does not exist does not cause runtime errors, it just does not happen !

So if we make a slight adjustment we see this :-

=================================================================================

Notice the order can be changed of the properties used, and the output is seen to be this :-

======================================

Once again, do NOT get confused about the data template driven display and the order in which we specified

out properties in the 'select' clause - the two things are quite different, and not related at all.

Let move on .................

PHH - 13th. August 2012.


the Target or Result

the Target or Result

the Target or Result

 Previous topic Next topic

Okay then folks, it is all too easy to get carried away with rushing off to examine 'clauses' and how to

use and apply them, before we actually think clearly about where our results 'set' will end up.

Yes, I think the first thing we need to learn about for query expressions (QEs) is where will the fruits

of our labours 'end up'. Into which collection object will our filtered and sorted data item objects get placed.

Well the syntax of the beginning of the query expression gives us some interesting clues.

let us look at a simple QE and then only the first couple of code lines - see below :-

====================================

Looking at the above image we see one obvious 'fact', the final object made by our QE will be called 'result'.

However, if we are now to ask "well what type of object is 'result' ?" we find we can't answer that question.

The very nature of us using the syntax ' var ' means to the compiler that we wish the Type to be determined by

what we include in the result of our query statement.

[ ** Note ** that in Vulcan.NET this is equivalent to 'LOCAL IMPLIED ........' ]

Let us go just that step further, and view a little more of a simple code expression.

Study the following CAREFULLY :-

============================================================================================================

It is the 'select' clause which determines the 'shape' of the query outcome.

So by line 55 saying just pass the whole source 'collection' object, into the target collection, then the Type

of the 'result' object has been determined.

It will be a collection of 'Customer' objects - 'Customer' being a custom business object class. (I made it.)

Okay then, so far so good !

Going that Step Further :

Lets take what we have above, and ask "what will we get if we choose only a few properties from the original source"?

Well, once again, if we examine some working code we get all the clues we require - see below :-

=============================================================================

The code on line 49 is telling the compiler to make a new object from the three properties included in the curly braces.

I would imagine that under the hood it is possibly making a 'result' class with properties exactly like those specified

from the original source object class - in the source collection.

We could even pencil this out for ourselves, it is not a complex problem.

Now then, just to prove to you that the first syntax you may grasp, or guess, at, does not work then study the following :-

===================================================================

In fact, it is obvious why this fails, once we start to think at an object and 'Type' level.

I have to admit however, that guys like me who are used to SQL querying with Management Studio, would try the above

syntax, just out of habit. The problem is with SQL tables and data fields, we have not got a source object as such.

So we can now make a short summary ..........

To Summarize, so far :

Once we specify our source collection, we can either produce a 'result' collection which has an identical object class

within it, or we can generate a new object class from specified single properties, and base the output collection (result)

on this new class.

PHH - 13th. August 2012.


From - (source)

From - (source)

 Previous topic Next topic

From - (source)

 Previous topic Next topic

In a Query Expression (QE) the first clause is the 'from' clause and this determines the source of the

collection data.

What can our 'sources' be ?

Well for what we are doing here with LINQ we need the source to be at least one 'collection', and a 'collection' is

a typed List or Array, or ObservableCollection.

If it were me I would steer clear of trying to use ArrayList, List<T> is much better in all ways, and in all

circumstances.

So in these eNotes I will be using List<T> and ObservableCollection<T>, which itself can be directly instantiated

from a List<T> object - that is one of its overloads.

I will leave it to you to try a typed array, such as an array of our Customer, or Order objects.

Technically, the requirement for a source collection is that the object is of a type which implements the 'IEnumerable'

interface.

Starting Simple :

Okay then folks, lets get some code going for us. We will start simply, and with only one collection referred to

in out 'from' clause.

===================================================================================================

Line 151 means that the collection is object with name 'oOrds' and that each item in the collection is to be

referred to as ' d '.

So in our example above ' d ' is an 'Order' object as defined by us previously.

So if ' d ' is an object then we can refer to its properties as seen in the next code image - see below :-

===================================================================================================

The results display from the above QE is shown next - check this out :-

====================================

The above GUI display is within a 'ListBox' control and without a specified template.

However, we can use the 'dot' notation in other parts of the QE as well.

Here is an expression in which we sort the items by data order :-

=================================================================================================

So in the above image line 152 has been added to cope with the sorting, and uses a property of ' d '.

Here is the results set shown below :-

====================

Lets move on to using multiple source collections ..............

Using Multiple Sources :

Okay then guys, lets up the stakes and play with two data sources - two collections.

In the following image we will use a collection of Customer objects and one or Order objects. Both of these

class types were defined by us in an earlier subsection.

The 'classic' way guys coming from 'SQL querying' are used to dealing with multiple data sources is via the JOIN

clause.

However, in QE we can do things differently, so be prepared for some new syntax.

Firstly, to keep SQL guys happy, here is a 'join' way of doing things - see below :-

==========================================================================================================

And this code produces the following output display in the 'ListBox' - check this out :-

=========================================================

That is what many folk would have expected to see in this section, but what about the next way we will

explore ?

How about two 'from' clauses, as seen in the code image below :-

===========================================================================================================

It all depends on the extra code we insert at line 52 (in this example) as to just how many items appear

in the final output collection.

We have limited our output such that the order data is ONLY for the customer - check this out first :-

=================================================================================================

So checking out the details above we see that 'Green' has order number d011, d008, d006 and d009.

This is what we call an 'INNER JOIN' in SQL query parlance.

BUT - what if we comment out code line 52 ? What do we see as results - check this out :-

==================================================================================================

The above details suggest to me that we have lots more result items in the final collection. In fact it would

appear that we have what is called a 'CROSS JOIN' and that for each item in Customers we have a combined

item with each item from the Orders collection.

Yes, I know, this is NOT a lot of use in most cases, since we have in this case orders like 'd002' which are

not belonging to 'Green'.

What of other types of joining, can this be done with multiple 'from' clauses ? I refer here to LEFT OUTER JOIN,

and RIGHT OUTER JOIN. These are very useful when the situation is right, so we need to know.

PHH - 11th. August 2012.


Select - (shape of result object)

Select - (shape of result object)

 Previous topic Next topic

Select - (shape of result object)

 Previous topic Next topic

Okay guys, lets start as simple as you can get with a Query Expression (QE) using a 'select' clause.

The 'Degenerate' QE :

This may appear so trivial that you think that we might as well use the original collection (or data source) - BUT -

better men than me say this :-

On the other hand, iterating directly over the data source skips the invocation of any custom Select extension method

and does not guarantee the correct behaviour - unless, of course, you explicitly want to iterate over the data source

without using LINQ.

Here is an example of such a 'degenerate' expression - see below :-

===============================================================================================================

The above code means that for every item within the original collection, the same item is placed in the

collection to be returned as a 'result' - here the object is entitled 'query'.

SO the 'query' collection is output as a collection of our Order class objects.

Just to show that this actually works, and produces data, here is a live output from the QE - see below :-

===============================================================

Lets move on to something more complex ................

Setting the 'Shape' of the output :

We need to realise what is meant when we say the 'select' clause determines the 'shape' of the result collection.

In our simple case above we have ' d ' representing an object of type 'Order. By coding the QE as 'select d' we mean

that any output item will also be a whole and complete 'Order' object.

However, most times we only wish to have a reduced number of properties in the collection items of the output collection.

The way we specify a new 'form' of object (or class on the fly) is shown below in the next example :-

==================================================================================================

On line 152 we have specified three properties which are to be included. You can think of this as passing through

properties, whereas others not specified are ignored as far as the output data is concerned.

Here is what we get in a ListBox control without any templates applied - check out the following :-

==============================================================

So far we have allowed our output properties to have names determined both by the system, and totally influenced by

the original names of properties on the source collection items.

Let us change this ..............

Renaming our Output Properties :

It can be very convenient at times to rename the output properties to something we choose ourselves.

This can be for various reasons, one being a poor choice of name in the original ;-)

Anyway, the choice is at least ours, and also note that we may chance zero, one, or more names - see below :-

===================================================================================================

In the above image I have specified all three output properties within our new object class.

The following image shows the results - well, part of them ! :-

===============================================================

Notice how the system prints the item properties in a 'ListBox' control without a template set by us.

Lets move on ........

'New Properties from Old' :

This sounds like a pantomime - 'new lamps from old', Aladdin ! ;-0)

However, we can do more with creating our new object properties than just 'pass through' those we already have.

We can make 'calculated' fields, or add some static values.

Now we will try something which is a bit silly for the data we have immediately available to us, but it will show what

can be done.

Checkout the following image :-

=====================================================================================================

In line 152 we have set two new properties, one a concatenation of two strings, the other a 'DateTime' value.

This looks like the following at runtime :-

============================================

Time to go further ................

Using Two Source Collections :

Okay then guys, if we are to use multiple sources and the 'join' clause on a regular basis, which I have suggested

in the 'Join' clause section, then we need to use properties in our output specification from more than one source

collection. This is not at all difficult.

Let us start with taking whole item objects from the original source collections - check this out below :-

==============================================================

In the above results we have used 'c' and 'o' to specify output - as seen in the next code image :-

===================================================================================================

Line 51 shows a commented test line, which in itself is useful as a guide to what may be done.

However, line 52 shows we are using all of the properties of the ' o ' collection and all those of the ' c '

collection as well.

Since we are specifying properties on an object class the order of specification is not as important

as when we use traditional SQL queries and the order in SELECT is the order of the columns in a table.

So don't worry about 'order', just make sure you get the properties you require.

Having said this, lets do a further test experiment to reverse the specified order - check this out :-

==============================================================

And now we need to see the code which produced this output above - see below :-

==================================================================================================

As already mentioned, the order of properties within a .NET object does not have any real meaning to the

developer guy, not like Table columns.

Lets move on to something trivial ?

Writing a 'Useless' QE !? :

At first glance the following seems silly at best - however - there are times when we need to output a

string constant, so we need to know that this can be done, as indeed it can in SQL querying.

==============================================================

We could also have given our property a name, like 'Silly', but I will leave you with the code that produced

the above output image - see below :-

=====================================================================

Well, I think that for the moment this will do for details and help on using the 'select' clause.

You can see more on 'select' in the subsection on Extension methods, and Lambda Expression use.

Time to move on.

See you in the next subsection on the 'where' clause.

PHH - 11th. August 2012.


Where - (filtering, reducing the results set)

Where - (filtering, reducing the results set)

 Previous topic Next topic

Where - (filtering, reducing the results set)

 Previous topic Next topic

This is probably the most common used 'optional' clause.

Although queries work well without any 'where' clause - when all object items within the source collection

will appear in the results collection - we as users VERY often need to include a 'where' clause to filter

the source items.

Where is commonly called the 'filter' clause, and we talk of 'filtering' our data.

To be quite honest with you using the 'where' clause is easy, but only if you are very careful with your logic

sub-clauses.

You are most likely to generate problems for yourself by writing compound 'where' clauses which logically

do something different to what you intend - often these results are 'blank' or 'empty' results collections.

Before we look at compound 'where' clauses, we need to see a few 'single' ones.

In the following image we are in the process of adding a single sub-clause 'where' line into our code.

Notice that we get a helpful intellisense drop list which contains the possible properties for selection.

Checkout the following :-

==================================================================================================

The full code line entry is now shown in the next image, and all red wavy lines of 'complaint' from the XAML

editor have disappeared - check this out below :-

=========================================================================

And if we compile and run with F5 we see this result shown below :-

===============================================================

However, if we are to extend this sub-clause to check for others too, we see we can write it as follows :-

=================================================================================================================

The ' || ' is a compound symbol with two 'pipe' characters, usually bottom left of keyboard. These represent logical 'OR'.

So the one 'where' sub-clause produces this output display :-

===========================================================

Do not rely on the order of these result, or output, items - we will deal with sorting in the next subsection.

Before we move on, lets change the source collection and then alter the script ever so slightly.

=================================================================================================================

And now we can study what these few lines select from the Orders collection - see below :-

========================================================================

I will leave it to you to visually check through the 'CustomerID' values in the above image.

Remember that in the Orders collection the 'CustomerID' is effectively the 'Foreign' key.

Lets move on ..........

Compound Filtering :

Okay then, lets change our filter expression for the Orders collection to be as

follows :-

=================================================================================================

In the above code we have a situation represented in which a user in the sales office is entering new orders

as they come in, here the office staff member (user) has an identity of 'u013'.

So if we run this code we should see all the orders this user has entered - check this out :-

=======================================================================

Okay, much as we suspected it would be.

But if we first expand our single sub-clause to include a possible other user we get this below :-

===================================================================================================

And once we run this code we get a group of results for the whole input period, as shown below :-

================================================================================================

Now the interesting part, suppose we are interested in orders taken by either user, BUT, only after

a certain date.

Lets say the 'cut-off' date we are interested in is July 31st. 2011, so we change the code to the following :-

=================================================================================================

So we see line 51 is the second sub-clause for filtering - the results of this are shown below :-

======================================================================

So it would appear that user with identity 'u013' did not make any orders.

Let us widen the filtering (or search) such that we also look at later dates - see the following image

and study it carefully :-

========================================================================================================================

So we have extended the second sub-clause to make it a compound sub-clause - Yep, we now have two

compound sub-clauses.

So what of the results sets ? - checkout the next image detail :-

===========================================================================================

Well, an easy way to tell that we have excluded some order items from the original collection, is to look

at the right hand edge, we see no scroll bar this time, and so we only have eight items in the results set.

I have just done a check, and we previously had 11 items when the scroll bar showed.

Moving on, lets try a third and compound sub-clause, I hope you don't start to get confused ;-)

Study this carefully :-

=================================================================================================================================================

So the third sub-clause further reduces out results set - or items in the 'result' collection - to those bellow :-

===========================================================================

Time to move on ..........

How to Read the Where clause :

Here is the part which humans make difficult for themselves because of the flexible way they speak and the

flexible way they talk.

The process of 'filtering' in essence is an active process of excluding some things (or stuff in Chemistry) and also

allowing other things (or stuff) to pass through the filter.

However, in our 'where' clause we actually make code statements ONLY about what items are to be allowed

through the filter - so we make code statements about what is to be 'included' and not what is to be filtered out.

So to summarize, it is in our 'where' clause and sub-clauses that we express what items are to be included in the

results collection.

So in man-in-the-street parlance we 'filter in' rather than 'filter out' !!!

Think hard about the above statements ;-)

Now, on the subject of ' && and || ' - ands and ors - we say that each && (and) applies another sub-clause, and

that each || (or) adds to the sub-clause and makes it compound in nature.

If you copy the code formatting I have used in the above images then yo will lessen the chance of you getting

your logic in a twist - we have all done it, it is easy to do, but with tidy formatting of your code it will happen

less frequently.

One simple tip I give (and follow) is to build up 'step-by-step' the filter statement, and check it out at each stage.

We could call this 'try as you build'.

Time to move on, what if we have more than one source collection ? ..................

Multiple Source Collections :

Okay you guys, we are doing very well so far, but now we must cover a VERY common case for using 'where'

clauses, and that is when we have multiple source collections and we make some filter conditions on properties

of items from one source, and then other filter conditions with properties on items from another source.

Fist of all we need a query expression (QE) which uses two sources and we then make no filtering at all - so

all the items turn up 'joined' in the results collection - checkout the following image :-

===========================================================================================================

In the above image the two source collections are Orders and Customers.

So the whole set of 'joined' items shows up like so - in the following image :-

=================================================================================================

Now we need to construct a 'where' clause which has parts filtering on Customers and other parts filtering

on Orders.

First of all lets slightly change the code above so that we use 'd' for Orders and not 'o', I think it is less confusing.

Also we will just filter on properties within 'c' or Customers - here are some results first :-

==========================================================

And now the code which filters (in) the Green and Brown and any White customers - check it out :-

================================================================================================================================

Notice that the fourth sub-clause condition is on the 'CreditLimit' property and not the Name one.

OK, I know, we can't see any output for 'CreditLimit', but you get the 'drift' of my discussion ;-)

Now we are going to add a second sub-clause to our 'where' and make a condition based on the Order properties, or

at least one of them - checkout below :-

=================================================================================================================================

So we are only including in our results set those joined items which represent orders after July 13th. 2011.

Here is what I get at this end :-

========================================================

And now, taking this a step further, let us add a third sub-clause using an Order property, and this time we will

make it a 'NOT' in logical parlance.

Let us say we want any customer adhering to the first few filter criteria, and then who are NOT customer with identity 'c008'.

Study the code below thoroughly :-

================================================================================================================================

And obviously we need to see what the result are that this code produces - check the following :-

================================================================================================

Well, certainly the order number 'doo8' has now gone from our results 'set' or collection.

Okay then, enough of filtering for now, lets move on, lets do some work with sorting ..............

PHH - 14th. August 2012.


OrderBy - (sorting result collection)

OrderBy - (sorting result collection)

 Previous topic Next topic

OrderBy - (sorting result collection)

 Previous topic Next topic

This is one of the most important subsections of these eNotes on LINQ.

Along with filtering, sorting data items by one or more properties is so common as to be indispensable !

So we have to get good at changing the order of items in a collection - AND - we must be able to make

compound and complex sorts too.

Lets start simple and gradually work our way up the complexity ladder.

A start - Simple Sort :

Lets us take our customer collection and sort the items by the property called 'CustomerID' which is on the

Customer objects - as defined in the 'Customer' class of our seen in a previous subsection.

Here is the visual display of the output :-

===========================

In the above image notice the order of the first column, 1, 3, 5 .......... 11, 13.

Here is the sort code used to create the above :-

========================================

Now you can see why we got the 'ListBox' display that we did.

Ascending and Descending :

If we need to sort our item order, we need to be able to set the type of order to Ascending and/or Descending.

In the above simple example we did not specify a type of order and so the default was applied of 'Ascending'.

Let us try and reverse this order by coding things a little differently :-

==========================

The items in the above image are sorted 13, 11, ............... 3, 1.

This is done by changing the code to the following :-

===================================================

Lets move on a pace ..............

Compound Sorting :

Lets make the above sort more complex, and use two separate properties.

Our data is not really very suitable as it is so limited in scope etc., but we can see if we are successful by

one pair of items.

Look at the following results, and in particular the last two items for 'Brown' :-

=========================

The names are Z- A and the identities are A-Z.

Here is the code we used - check it out against what we said in the last line :-

========================================================================

Lets move on, and learn some more .........

Taking complexity a step further :

If we use the small amount of data we do have, in a suitable way, we can see the effect of at

least a three property sort.

However, the sort I will demonstrate is actually a four property one, we just don't have enough data to see

that it works - it certainly compiles and runs ;-)

Check this out :-

================================

At the bottom we have three postcodes the same, then the names in order Z-A followed by the

'CustomerID' in order A-Z.

Study the code in the next image very CAREFULLY :-

======================================================================================================

There you are, that should give you enough knowledge and ideas to allow most sort orders to be achieved ;-)

Lets us now move on to another subsection.

Let us move to the Join subsection where we see how to 'de-normalise' two or more collections.

See you there ...................................

PHH - 14th. August 2012.


Join - (combining source collections)

Join - (combining source collections)

 Previous topic Next topic

Join - (combining source collections)

 Previous topic Next topic

Okay guys, are you up for it ? An intellectual bit of fun I mean !

Because 'Joins' are fun, but also extremely useful, and some would also say 'necessary'

From my previous SQL query statement experience I know that with just two 'flavours' of joins we can

attempt to solve most of our 'day to day' problems.

The 'Inner' join and the 'Left Outer' join are what I am talking about.

If really necessary the 'Right Outer' join can be achieved by reversing the two input collection sources.

What is it that we 'Join' ? :

This is a VERY important question to ask, and also very to answer correctly.

We join two collection (data) sources, but not just ANY sources.

It has to be remembered that JOIN in SQL Server parlance came about because we 'Normalise' our data in

a relational database system.

Items of data should only be stored once, and in one place in our DB (data base). This is done with a system

of primary and foreign keys.

So to make a report of orders for customers we need to re-connect all the items of data for the report details.

Orders for a particular customer will not have any information regarding the customer address and name etc., so

we would need to join two collections, one for Customer details, and one for order details.

Think of these two 'chunks' of data as being joined 'side by side', the link being the identity for the customer.

*** NOTE *** joining as a 'Union' :

I think at this point it is good to make a note that the general word 'joining' may apply to a rather different situation.

Sometimes we will have two sets (or sources) of data, and we will wish to make then 'one'.

If however, these sets are of similar structure (say both based on Orders) then we are said to carry out 'set algebra'

and these two data sets and merged with the 'Union' operator.

See another section for "Union, Intersection and Except".

Here, and throughout LINQ technology, when we talk of JOIN we are de-normalising to create longer 'rows' of data items

all relating to one aspect for a report type output.

Joining is the other side of 'Normalising' ! That is the best way to see it.

Now for an Example :

I have some suitable data with which we can do a few useful tests.

Earlier in the eNotes I made a class of business object called, 'Customer' and also 'Order'.

In both class definitions we included a property called 'CustomerID', and this is what we will use to bring the two data

sources together - side by side !

PLEASE be aware that in real life SQL databases, the column name in one Table is not necessarily the same name as

that in another table, even if the data contents of that field/column are similar. That's just a fact of life ;-)

Because we designed and made our classes at the same time, and with an eye to doing this exploration, we called both

of our properties 'CustomerID'.

Lets start with some visual success, here are the results of our first 'Join' :-

======================================================================

As you can see in the above image we seem to have data for the same customer, a Mr/Mrs/Miss Green.

So what sort of QE produced this results set ? How was our final collection put together ?

We need to study the following code image carefully :-

=======================================================================================

Before we discuss a little about the action of the 'select' clause, let us remind ourselves of the data items

relating to customer 'Green', or should I say more precisely customer with identity 'c011'.

Check this out :-

==========================================================================================================================================================

An now the objects within the collection of Orders :-

====================================================================================================================

Okay that looks fine, lets move on a pace ..........

Simple Question !? :

Let me test you, if for some (strange?) reason we had another customer with identity 'c011', what would we expect

to see when we re-run the same query expression ?

Well, instead of guessing - although we all like interesting questions - let do a real life test instead.

Firstly lets see the visual result, see below :-

=====================================================================

Yes, we see that for each object in the first collection we get a 'joined' row or new object, for each matching object in

the second collection source.

So here is the 'offending'? extra customer data object - check this out :-

===============================================================================================================================================================

Time to look at 'selecting' ...........

A short word about Selecting :

Now our query code shows we have lines 63 and 64 which use collections of Customer objects and Order objects.

In our 'select' clause we have about three options, to output into a results collection either one or the other of the

original objects, or to build a new object based on some or all of the properties within the original two.

In the one you saw used above, we are making a new class of object, based on the properties we have chosen.

Lets try doing this differently - see the following two images :-

======================================================

Notice we have gone back to only one Green and 'c011' entry, just to simplify things a little.

The code producing this output has a different format in the 'select' clause - see below :-

===========================================================

Knowing this syntax above, we can now make sense of what we saw visually in the GUI 'ListBox'.

because we are not using any DataTemplate the list item display is handled by the system.

We see 'o = .... ' and 'c = .... ' and each is using the ToString method I wrote for us in the class definition of

Customer and Order.

So line 67 seen above is a fast and shorthand way of saying all properties from one plus all properties of the other.

Obviously, we ought to be able to choose only one, or the other, lets try just ' o ' - see below :-

===================================

And here is the code for the above output :-

===========================================================

Be aware, that is this not as flexible as some places I used to write SQL queries, and multiple entry of any one

property is not permitted - so no duplications.

Also, because we have objects with properties, the order of the class defined properties is rather meaningless,

compared to the position of a column in a table.

So although both the following works, I can't see why one would be used in place of the other :-

========================================

And if you think that was a bit silly, then what about this below :-

Silly Output !? :

Okay then, judge for yourself :-

=========================

And this output is from the following code with 'select' syntax producing a single string constant :-

====================================================================

Although this seems 'silly' there may be times when we need to output a constant, or other fixed value for a particular

property of our new output object in the results collection.

Lets move on to something which may be far more useful. What about naming the new properties ?

Providing Property Names :

Lets us take the first example where we have a new output object we are defining, and in place of the original

property names we wish to replace some or all of them.

Here are some results before we study the code and syntax :-

[ .. note this is a default item list by the system itself .. ]

===========================================================================

So what do we have to do to change the names ? - check this out below :-

===================================================================================================================================================

Note that if no new name is provided then the existing property names is used.

Left Outer Join :

For anyone coming to LINQ from the world of SQL query statements, they will recognise the use of LEFT OUTER

JOINs (LOJ) to solve problems. We therefore need to be able to reproduce this in LINQ code and QEs too.

A 'LOJ' gives us all of our items (records) from the first, or left collection (reading left to right), and matched properties

or nulls from the second collection.

Look at the output data in the following image to see we effectively have a LOJ showing below :-

================================================================================================

Reading the details above we can say that from all the items on display only customer 'Smith' (ID = c003 ) has

no orders recorded in the system.

The following code is what produces the full LOJ collection of items:-

=======================================================================================================

But what if we were just interested in those records, or items, for which there was no join-up ?

Well, that can be achieved too, so study carefully the code in the image after we see success in the display area :-

=================================================================================================

Yep! the code below list for us what we are after, and nothing more : -

===========================================================================================================

Code line 58 is what effectively filters out all customers with orders - BUT ......

Oh! dear !! - after years of telling myself in SQL querying that there is not an equal to null 'approach' but an 'IS NULL'

one, we see the syntax in C# as above on line 58 :((

For you new to this you must read it as 'where jc is a null object', which is quite different I can assure you.

I had better stop here before the whole can of worms opens up ;-0)

Notice however that lines 56 and 57 will cause errors as we are instructing the compiler to look at a property on an

object will does not exist, 'jc' is a 'null object'.

PHH - 11th. August 2012.


Group - (on the results set)

Group - (on the results set)

 Previous topic Next topic

Group - (on the results set)

 Previous topic Next topic

As I said in an earlier section, 'Groping' using the 'group' clause is possibly something that new guys

get around to ONLY after they have mastered a lot of the other, and 'more basic' ? stuff.

However, grouping can be very useful, and I know that I got around to using it a lot in SQL querying,

BUT, once again it took me a while to get there ;-)

Now I don't know how I managed without it.

So lets ease into this grouping 'idea' slowly, a step at a time.

PHH - 11th. August 2012.


Let

Let

Let

 Previous topic Next topic

PHH - 12th. August 2012.


Using Input Variables

Using Input Variables

Using Input Variables

 Previous topic Next topic

We now need to see just how much more flexible we can make this code used by us for querying.

It will be very convenient for us, while developing solutions, to be able to provide a variable input to our QE than just a

fixed or constant value.

Let us explore some possibilities in this section, and we can start very simply as shown below :-

================================================================================================================

As you can see in the above code line 53 now takes a variable for comparison instead of a string constant.

PHH - 14th. August 2012.


Enumerating Collections

Enumerating Collections

Enumerating Collections

 Previous topic Next topic

Okay then guys, once we have a collection (or a few) we will need to go through it and 'do things' with

the items in that collection.

Going through a collection one item at a time is called 'enumerating' the collection.

Usually this is in a forward direction only, as well as read / only.

Certainly these 'restrictions' are not a problem when it comes to examination of items and their properties.

Once you get a few examples under your belt you will be 'on your way'.

Take a look at this string output from one of our collections :-

Well, the above text output displayed in a single TextBlock control, is a good first example of how we

can carry out enumeration - checkout the following code :-

===================================================================================================

In the above code image we see that lines 79 through 82 are those forming what is known as the enumeration.

Notice once more that we use ' var ' in the 'foreach' statement as we may not know exactly of what type the items in

the collection actually are. remember ' var ' is like Vulcan's 'LOCAL IMPLIED'.

In fact you may be interested to see the next image where the intellisense is giving us some useful feed-back.

=================================================================================================

And the intellisense system is also helpful with prompting us with property names too - see the next image :-

============================================================================================================

Okay then, lets now move on to nested enumerations ............

Nested Enumerations :

This technique is probably best seen with a 'grouped' collection. This is one in which the items within the main

group each have a property which is also a collection.

So we need to go and make our own ;-)

=======================================================

============================================================

====================================================================

==============

Yep! so customer '3' has no order - identity 'c003' that is, 'Smith'.

=============================================================================================================================

PHH - 15th. August 2012.


Chapter 5 -

ClickStartLINQ

Chapter 5 - LINQ to Objects

Chapter 5 - LINQ to Objects

 Previous topic Next topic

Chapter 5 - LINQ to Objects

 Previous topic Next topic

Let me try and make one thing clear to me and your good selves, LINQ as a technology, allows

us to write code to use with in-memory objects - the sort of objects that you and I call Business

Objects, as well as also to use data in SQL Tables on a backing store - disk to you and me ;-)

One of the whole points about LINQ is to unify the way we think and write code about data access.

So there is MUCH similarity between how we deal with items in collections (LINQ to Objects) and

data rows in SQL Tables.

Obviously, we have to make some sort of coding efforts to get our Table structures into .NET classes

of objects, then much of the syntax is exactly the same.

For many of us it may be unfortunate that we seem to have two ways to code much of this, Expressions,

and then Extension methods taking Lambda expressions - Query Operators approach.

To be honest, after a good bit of trial and error - learning to you and me - it all becomes quite easy to

apply any of this stuff.

Just make sure you have some good learning materials, as well as 'ClickStartLINQ' available to you

at all times.

In the following couple of subsections we will look in detail at the Query Operators, as these provide a

VERY flexible way of writing LINQ code.

It is my personal feeling that these are used to support the Query Expression style of coding I have used

extensively up to this point in these eNotes.

PHH - 14th. August 2012.


the Query Operators

the Query Operators

the Query Operators

 Previous topic Next topic

The 'Query Operators' are based on a C# feature called 'Extension Methods' (EM).

EMs are a bunch of extra methods which can be applied to an existing class without such 'named' methods.

Let us take the simplest of cases for our first example.

Let us make a collection object ( List<T> ) which has one extension method applied to it - see image below :-

=============================================================================================================

In the above image line 143 uses the 'Select' extension method which is applied to the collection.

Before we move on to see more, let us view the results that are output :-

===============================================================

In our simple example we get the same results as if we had done the following :-

============================================================================================================

However, you will soon start to see some quick and great results when we use other extension methods, and a

range of input parameters too.

============================================================================================================

=========================================================================================================

==========================================================================================================

======================================

================================================================================

==================================================================================================================================

================================================================================================================================================================

=======================================================================================================================

===========================

====================================================================

===============================================================

============================================================================================================

========================================================================================================================

===============================================================

====================

==========================================================================

====================

=====================================================================

PHH - 14th. 2012.


.Single

.Single

.Single

 Previous topic Next topic

Single, Many, and No finds - and errors too :

Let us now look at the case of us wishing to get a single row returned to make us a single item for our collection.

There are a few things we need to know about 'singles' as well as what to do when things go wrong.

Below is a live example from the AW12 database we downloaded - check this out :-

================================================================================================================================

==========================================================================================================================

==========================================================================================================================

=======================================================================================================================================

PHH - 19th. August 2012.


Order of the Operators

Order of the Operators

Order of the Operators

 Previous topic Next topic

My advice would be simply to 'take CARE' and apply them in an order that makes sense to you and your project in hand.

Getting the order wrong will not always show up as an error in the editor, but obviously some cases will. It just depends.

And, some errors in order of operators applied will only show up in the resulting data - so test thoroughly, and test with

meaningful test data.

So I suppose this once again comes down to knowledge and gained experience ;-0)

=======================================================================================================================

==============================

===========================================================================================================

=========================

===================================================================================

=================================================================================

============================================================================================================

===========================================

===========================================================================================================

===========================

PHH - 13th. August 2012.


Chapter 6 - Conversion Operators

Chapter 6 - Conversion Operators

Chapter 6 - Conversion Operators

 Previous topic Next topic

AsEnumerable

ToArray

ToList

ToDictionary

ToLookup

OfType

Cast

*** AsQueryable ***

PHH - 14th. August 2012.


Chapter 7 -

Chapter 7 -

Chapter 7 -

Previous topic Next topic

PHH - 11th. August 2012.


Chapter 8 - Object Services

Chapter 8 - Object Services

Chapter 8 - Object Services

 Previous topic Next topic

=======================================================================================================================

====================================================================================================

===================================================================================================================

PHH - 14th. 2012.


Chapter 9 - WPF with C#

Chapter 9 - WPF with C#

Chapter 9 - WPF with C#

 Previous topic Next topic

One of the main reasons fro me switching back from using METRO for development and testing of Apps using LINQ is

because with WPF we do not encounter problems of sandboxes, and being forced to make an extra data access layer

with WCF, and all that stuff.

A some of you may know, it is hard enough to get SQL Server installed and up and running with an 'attached' database

without any other problems. SO for the present, while developing our LINQ to SQL skills, we will stick with WPF and

.NET 4.0 to use with MSSS version 2012, codenamed 'Denali'.

There are other sections of these eNotes on installing MSSS and the AdventureWorks2012 database, for the present we

will assume that we/you have SQL Server available, and that you know your connection string - Appendix C will help you.

Also there is a subsection in the 'Introduction' entitled "Setting up SQL Server and a DB", which will also help you.

In the test code shown in the following image we see that my connection string is shown on lines 45 and 46, as well as

the 'MessageBox' output string. Also note that there is code to set or open the connection - see below :-

===========================================================================================================================================================================

You may be interested to know that as shown in Appendix C, my 'Server Name' is "BEST-V64QUAD\DENALI_DEV_2012" and this

has been made by the system from the name of my PC (now about 7 years old!) and the name of the SQL Server.

In the above image we have placed the string for the connection in a STATIC property, and also have a STATIC test method

for checking we can 'Open' a suitable connection.

Unless we get a couple of messages similar to those shown above, it is no point going any further :(

PHH - 14th. August 2012.


In-Memory Collections

In-Memory Collections

In-Memory Collections

 Previous topic Next topic

Working with data in memory looks VERY similar in syntax terms.

However, we are NOT using DataContext, which is what makes 'LINQ to SQL' work for us.

So what we will see in the rest of this subsection is querying in-memory 'stuff' and not using 'DataContext'.

For this introduction to C# with WPF, we will just see in action some simple examples of how SQL back-end data

may be retrieved using some straightforward coded query statements.

Let us first examine how easy it is to find those customers who have not made an order.

Let us make two generic List<T> objects, one based on 'Customer' objects and the other on 'Order' objects :-

============================================================================================================

If you find it difficult to read the above code - or should I say understand it - then don't worry, it will come to you in time,

it just takes some experimenting, and lots of trial and error stuff ;-)

Anyway, here is the result of our 'live' query - see below :-

==========================

Which is correct! So what does our code do ?

Reading the Query Code :

In the code image above line 145 is the crucial one - it either accepts or rejects the customer in focus from the list of customers.

First we have a 'from' sub -clause which makes a list of only the customer IDs in all the order objects. Now we can ask if this

list contains the customer identity of the customer in focus - and if it does then the query moves on to the next object in the

customer list. So if it is found it is rejected, so to speak.

Line 146 is only applied when the customer list from orders does NOT contain the customer ID in focus - being used.

The 'select' code statement effectively allows us to output any property of the customer object found to NOT be in the list

of orders.

You may need to re-reading the code above, and think about it a lot, especially if you are not experienced in SQL query use.

Now then, something much simpler, lets examine the code for the 'list of order' - see below :-

==========================================================================================================================

This list looks like the following image when we use it on its own and display in on a WPF form, within a list

control - check it out :-

================================================================

The code to make this display is shown in the following image :-

====================================================================================================

Of course there is also a line of code to bind the 'query' data to the WPF form or ListBox if we are working

at a basic test level - like that below :-

=========================================================

And then the XAML script to match up with this - see below :-

=========================================================================================================

Okay then, so good, so far.

But lets go a little bit (a useful bit) further, and get a list of unique (or distinct) entries - see below for results :-

===============================================================

Yep! a unique list all right, BUT, it is not order as yet. The last element is out of place.

First lets see the query code in C# which gives us a distinct or unique list :-

====================================================================================================

And now if we see an ordered list - as shown below :-

================================================================

We can wonder how this was done, and to find out we look at the final image in out little test - see below :-

==================================================================================================

So we have started into this new chapter on C# with WPF with some success with in-Memory code.

However, it is when we get to using SQL Server back-end databases that this section will come into

its own.

But first we need to put a few new things in place, and built up some prior knowledge on which to base

our later work on 'LINQ to SQL'.

Time to move on - see you in the next subsection.

PHH - 11th. August 2012.


Our Own Comany example

Our Own Comany example

Our Own Comany example

 Previous topic Next topic

====================================================================

=================================================================

============================================================================================

=======================================================================

===================================================================================================================================================================

=================================================================================================================================================

===============================================================================================================================================================

=====================================================================================================

========================================================================================================================================================

==========================================================================================================================================================

==========================================================================================================

PHH - 16th. August 2012.


AdventureWorks (2012)

AdventureWorks (2012)

 Previous topic Next topic

AdventureWorks (2012)

 Previous topic Next topic

In this subsection we will use the 'AdventureWorks2012' database file I downloaded from the web,

see the Introduction for how to do this. The file is an '.mdf' format.

We will also have this database attached to the full version of the 'Denali' SQL Server - that is MSSS 2012.

I will find a suitable connection string for my development PC platform, and the first image, shown below

starts at this point.

Note the commented lines were from a first attempt at connection, where I was using a tried and trusted DB.

Check this out :-

==========================================================================================================================================================================

Well, I go the connection to open, and also a suitable couple of messages in my display 'MessageBoxes' too.

In due course we will tidy up this code, but for now (this subsection) we are looking for some success ;-)

Now then, in Management Studio (MS) we can display a limited number of the tables in AW12 by setting a

filter on the Tables folder / node.

The next two images show what this looks like and also how to do it after right clicking for the context menu

on the Tables node in the Object Explorer (OE).

Check out that the Person 'schema' is the only set of Tables on show :-

=================================================================================================================================================================================

Now then, the whole purpose of using AW12 is to get at some quick and easy data (lots of it), and we

can select table entitled 'Address' in the 'Person' schema for this purpose.

In the following image we see the list of columns / fields present on our table SQL object.

Study the list of columns names and their related data types - see below :-

==========================================================

Okay then guys, here is the 'necessary' part which ever way you use a SQL back-end data source for .NET

object use - use within business logic.

We MUST make a mapping between the columns in the table and the properties of our .NET object.

Any way of doing the mapping (LINQ, or my STATIC methods) allows for us to have different names on

either side of the 'mapping', that is an option. However, we MUST clearly define what data types are involved

at both ends of this mapping.

At the moment most of the properties are simple - 'string's and 'int's but we get more ambitious later on.

See below for details :-

=============================================================================================================================

Oh! in the above image we do have a more 'interesting' data type, that of 'Guid', but we do need to explore

more at a later stage.

Also notice that when we do a 'mapping' of table columns to in-memory object class, we do NOT need to use

all columns.

In fact this is one very useful and flexible approach, in which we can have different .NET objects mapped from

the one (same) table. Once again we will see more on this later on.

You will be interested in the next image where we show two ways to display the actual SQL statement sent to

the SQL Server via the underlying ADO.NET support code / stuff.

Checkout lines 69 and 71 below :-

=====================================================================================================================================================

In the above image you see code I tried and which did NOT give me all I was hoping for :(

The lines numbered 73 to 78 did not give me a simple 'MessageBox' output, because we actually have far too many.

In fact I was trying to print out about 20,000 lines !!!

So what I did was use MS to fashion together a suitable SQL query which would reduce the number of returned data

rows, and hence items in our .NET collection.

Below is shown the MS shell testing :-

==============================================================================================

Okay then 12 lines I think we can handle ;-0)

If we now place the filter conditions within our LINQ statement (expression) we can try a re-test.

Lets give it a go now :-

=================================================================================================================

Well, the first 'MessageBox' information is encouraging, so what next ?

Checkout the details in this larger 'MessageBox' display :-

=======================================================================================

Yep! all for Frankfurt.

*** CARE *** with numbers of records returned !!

I was using a simple 'MessageBox' for testing purposes - BUT - the AdventureWorks2012 database is much more

substantial than the ones we have been used to use for testing and trialling - almost 20,000 are returned if a

suitable filter condition is not applied.

As you can see our test code can handle twelve returned items ;-0) It is all too easy to look for errors in the more

complex stuff !

What we need is a suitable control on our WPF window. So below I show the code to bind the created 'collection'

called 'query' with the newly added DataGrid control on our WPF 'MainWindow'.

Checkout the code before I clean it up, as this indicates where we have come from - see below :-

================================================================================================================================================================================

Now then, lets get bold and try the full set of rows in the 'Person.Address' table, all 19,614 of them.

First we need to comment part of the filter condition, we don't want to go too far in one 'jump' so lets

stick with those guys from 'Frankfurt' :-

===================================================================================================

Well, that proved Okay, so lets go the whole 'hog' and have no filter condition at all :-

=======================================================================================================================

Yep! as you can see we can handle that just fine, the 'DataGrid' control scrolls nicely, and even sorts from the column headers

quite nicely too, even though there are almost 20,000 records.

The Data Binding end of things :

Before we finish this subsection we need to see what had to be done to bind the collection returned by the LINQ

query.

Well, not a great deal, it has to be said ;-)

XAML script lines 5 and 9 are al that is required in the WPF / XAML design surface - see below :-

=========================================================================================================

However, having checkout one end of the data binding, we need to see what is done at the other - in this case

within our .NET code - see line 110 below, that's all it takes :-

========================================================================================================================================

You can see that on line 6 of the XAMl script we named our main Window 'OurMainWPF'.

It is sufficient to bind the collection object to the Window. Any controls used in binding may require that we specify

'Path' attribute values, but that is shown in later sections of these eNotes.

Time to move on, before we get too complex, with many 'Joins' we need to explore what we can do with 'localdb' as

our SQL Server instance.

See you in the next section .................

PHH - 16th. August 2012.


Local DB with AW12

Local DB with AW12

Local DB with AW12

 Previous topic Next topic

*** WARNING ***

Although I will show how to use 'localdb' with both Management Studio and our own .NET coded application,

there is a restriction on 'localdb' which is that there can be only one connection - if I understand things correctly.

Certainly yesterday, while developing the material for this section (and others?) I found I had problems with the

AW12 database attached to the local sever in MS and me trying to run app code against it too.

For this reason I am doing most of my learning exploration stuff with the full version of 'Denali'. I suggest you

do the same.

*** possible trick *** since using AW12 is by most ways a read only experience for us while learning, we could

carry out a bit of 'sleight of hand' and have two copies of the AW12 data file, in tow accessible folders (security wise).

This means you can examine and explore AW12 in MS while running .NET code against the other - Oh! just thought,

maybe it is the local Server itself which can only have the one connection - silly me, this makes more sense.

If this is the case, then you would be better advised to use a full express version of Server 2012.

===============================================================================

Well guys there is plenty of material in the Introduction (last section) as well as in the Appendix C section,

to tell you how to download and install the full version and 'localdb' version of SQL Server 2012 ('Denali').

There is also plenty of help with you finding your own connection string and name of the full Server instance.

The name of the Local DB is fixed for all installations, for developer, client and customer. The fixed name

is ' (localdb)\v11.0 ' as 'Denali' is version 11 of MSSS, called by other 2012 as a 'public' or commercial name.

I will show you in this section how it is as easy to attach and code to AdeventureWorks2012 database using

the 'local' server as it is with the full version of the server.

Checkout the following images in which the code changes have been made - only small ones really :-

======================================================================================================================================================

In the above image, lines 33, 36 and 38 are where changes have been made from the earlier full version code.

We also need to remember the change of connection string we also made, and which was shown in Appendix C.

Check this out :-

=======================================================================================================================================

This should be reasonably familiar by now, if you have read the other sections I suggested, that is ;-)

Lets move on to Data Types ...............

Using More Complex and Varied Data Types :

So far in the last section we read in data from the Address table, but only for fields / columns with 'string' data types.

[ Oh! sorry, there was one other type, an 'int' - but this is simple too. ]

Let us now more on a pace and try out a few others, and see how we need to adjust our code to cope with these.

Let us start by trying a 'DateTime' object property, or table field /column.

======================================================================================================================================================

In the above image we need to note a couple of things, one that we can add the data type in a similar way to the

way we handled the 'string' type, the other is that we can sort the 'DataGrid' control by clicking the header.

Line 132 also has some useful advice, and that is if we misspell a Column name for the database, it is not picked up

until runtime - I found this by mistake when I omitted the 'o' from modified.

========================================================================================================

Lets move on ..........

What of other Data Types ? :

Well, maybe we can find ways of dealing with all types, no matter how complex !?

First of all take a look at the highlighted field in the following image, and then one one beneath that too.

Check this out :-

=========================================================================================================================================================

It seems we can start with 'rowguid' as seen in my next couple of images :-

=======================================================================================================================================

===================================================================================================================================

When we run the newly adjusted code we get the following output :-

Yep! so we can handle 'guids' OK, but what of 'geography' ? I have to be honest its a new one on me ;-)

Having done a bit of exploring just there now, I think we ought to try our a few more typical, or standard

types before we attempt to sort out 'geography' !!

Lets Look at Sales and Money :

In the 'Sales' schema for the 'AdventureWorks12' database, we see the following table called 'SalesOrderDetail'.

This table has a suitable number of (just a few) columns and their attendant data types.

You will also notice that we have quite a range of data types, many new to us in this exploratory exercise - see below :-

==========================================================

Let us see if we can make a new .NET class to allow us to read-in this data, all of the fields available to us.

Because we are not yet concerned about writing-back any data, we can leave the Primary Key (PK) and

Foreign Key (FK) issues to one side for now.

Let us get a good few columns/properties done before we try a compile and run test. Check this out carefully :-

==========================================================================================================================================================================

Well, since what we have done so far seems to work OK, lets try the last few properties - see below :-

================================================================================================================================================================

In the last couple of images I would like you to look VERY carefully at how we managed to change (or map) names

in our object class with different forms of the same name in the Table.

Even the table is named differently to our class 'SalesOrderDetail' to 'SalesOrderItem'.

A couple of properties are 'LineTotal' <> 'Total' and 'UnitPriceDiscount' <> 'UPDiscount'. You try spotting a few more

for yourself.

PHH - 17th. August 2012.


ADO.NET ?

ADO.NET ?

 Previous topic Next topic

ADO.NET ?

 Previous topic Next topic

Hi guys, well this section was to be helpful to you - BUT - it looks as if there will be nothing to say ;-)

It would appear from what work I have explored at the moment with LINQ that 'LINQ to SQL' uses

ADO.NET but all under the hood.

This means that all the ADO.NET classes and members that were used to make my STATIC classes

needed to support my earlier SQL work with Vulcan.NET are not required if I am to use 'LINQ to SQL'

with C#.

The entity model used by 'LINQ to SQL' allows us to use object syntax with our custom and business

objects and logic section - throughout. No need to dip down as far as ADO.NET.

For some of you who have looked at any of my recent eNotes for using SQL with Vulcan.NET you may

recognise the following image details - see below :-

=================================================

Layer 6 in the above image is purely ADO.NET 'stuff' which applies to all SQL applications.

Layer 5 is that layer where I customise a few members in a STATIC class to interface between the business

logic and the fixed ADO.NET members.

Well, until sometime in the future when we get LINQ capabilities in Vulcan.NET you can still do this, and use

my STATIC classes as seen later in this short section.

However, for C# code and us using LINQ technology, we no longer need to worry about ADO.NET or even opening

and closing connections if we go about things 'right' - 'using' may be the way to get around the open/close issues.

Layer 6 - 'SQL_my_funcs' :

===========================================================================================

Layer 5 - (ADO Business Objects) :

Working example - 'SQL_GroundProbe' :

An application called 'Ground Probe' is one I am currently working on in Vulcan.NET.

The customised class and members look like the following - code collapsed in the main part for clarity.

Checkout below :-

===================================================================

=================================================================================================================

Layer 6 - 'SQL_my_funcs' :

===================================================================================================================

=============================================================================================================

======================================================================================

===================================================================

PHH - 11th. August 2012.


Making more Classes - for AW12

Making more Classes - for AW12

Making more Classes - for AW12

 Previous topic Next topic

Well guys, we need to realise that before we can get to doing some interesting things with the data

in the Tbales of the AW12 database, we need to create ourselves a few more classes.

By this I mean we need to do a bunch of 'mapping', and make ourselves things like order header, and

order item (detail), as well as product and customers for AW and not our simple test.

To this end I have renamed our earlier attempt at customer to 'OurCustomer', and the

Having Problems - runtime errors ? :

The process of mapping

=============================================================================================================================

Problems with NULLs !? :

=================================================================================

==========================================================================================================================================

============================================================================================================================================================

========================================================================================================

Product :

============================================================

====================================================================================================

=================================================================================================================================================================

PHH - 18th. August 2012.


Classes from 'Views'

Classes from 'Views'

Classes from 'Views'

 Previous topic Next topic

We had better have a look at making some of our classes from 'View' objects in the SQL database.

It is not correct to think we can just make .NET classes based on Tables in a SQL database.

As users of SQL Serve know, often 'views' are used in query statement in place of a table.

Below is a view which is to be found in the Sales schema of the 'AW12' database - check it out :-

==============================================================================================

And we can base a query on this in MS as if it were a Table.

Here is a working example to show you what I mean :-

============================================================================================================================================================================================================

==================================================================================================================================

PHH - 18th. August 2012.


Many Tables, one Collection

Many Tables, one Collection

Many Tables, one Collection

 Previous topic Next topic

Okay guys, time to put things to the test - our knowledge of table collections and how to join them

together (de-normalising) to get 'long lines' as such.

Here is how I am used to doing it with SQL Server, and in the MS 'shell' - check this out :-

Notice in the image above we getexactly 3400 rows - see bottom right hand side (RHS).

Now if we apply the LINQ syntax we have been getting used to we can compose something like that code in the image below :-

=====================================================================================================================================

Once again we get the same number of items in our results collection - 3400.

Now keeping all the code the same lets see what results in our grid this produces - check below :-

===================================================================================================================================================================

Okay this is good, we seem to have the right amount of data - BUT - it does not look much fun :(

So we need to select specific fields / properties and this is done in the next image :-

============================================================================================================================================================================

Note we can't duplicate the 'c.CustomerID' and 'h.CustomerID' properties, the system won't allow it.

==================================================================================================================================================

There will be a way to declare this with a unique identifier / name, we just need to research how to do it !?

Oh! that was easy, here is a solution thanks to MSDN help pages ;-)

===============================================================================================================================

Notice how we place the new name on the left (no quotes used), and the the assignment operator and the old property 'value' ?

Whatever it is called, the approach works and so calculated fields / properties can also be added in this manner !!

Checkout the new data column as it is displayed in the DataGrid control :-

=================================================================================================================================================

Also we need to know that we do not need to have all the available properties output, AND, that any order

seems acceptable too.

You now may like to see what the actual SQL query looks like for this LINQ expression, this will be what is sent

vis ADO.NET by the underlying system.

Check this out :-

===================================================================================================================================================

And guess what, this is just the 'unfriendly' version of what I scripted original in T-SQL script within MS ;-0)

Time to move on I feel. Are you feeling up to a 'double join' perhaps ? maybe using some products ??

PHH - 18th. August 2012.


Scalar Values from Tables

Scalar Values from Tables

Scalar Values from Tables

 Previous topic Next topic

Okay you guys, a new day, a fresh topic area ;-)

In the following subsection we are going to see how we can 'read' back-end SQL databases to get back single values.

When we deal directly in SQL query statements, or ADO.NET, we term these 'scalar' values. A scalar value is therefore

any data type which is not a list, array or collection of any sort.

While looking at how to read back data values of a scalar nature, we can make sure we cover a wide range of basic data types.

Okay then, to begin with we will stay with the 'OrderHeader' class which lets us query via LINQ the 'Sales.SalesOrderHeader'

table in the AW12 database.

Just to remind you of the structure of our .NET class (along with the mapping) here it is shown below - check it out :-

[ .. note the lines 7-11 for extra necessary namespaces .. ]

=======================================================================================================================

A couple of things to note; one that SQL Server data type 'bit' maps to our .NET Boolean type, and since we do not have any

string data types all the others need to be specified as 'Nullable' types.

Another thing is that if we were ONLY going to use this class to read data from the Table then we could simplify the details

used in the mapping process. I don't really recommend this but we need to see what is going on.

In the following image I have commented the fuller version and cut out as much as possible of the column specification,

testing at each stage to see when things failed !

Check this out both fully and carefully :-

=====================================================================================================================================

Okay then, enough of checking over the class to be used in our LINQ querying.

Let us now use a QE - query expression - much in the same way as we have seen them used in previous sections.

All we will do is apply the extra Extension Method 'Average' to the QE select statement, and for the moment we will

still call our output 'result' - see below :-

=====================================================================================================================================

Obviously, to force the code to run when we compile and launch the app, we need to do something like this

shown below :-

=======================================================================

So let us try and improve on our coding somewhat.

Notice in the following image we can name the output variable with a more meaningful name, as well as suggest

a possible data type.

=====================================================================================================================================

At first I thought the average was a little high, but then I am not familiar with the AW12 data.

However, it would appear from further work shown below that this is indeed correct.

Now lets try an make a few more 'aggregate' variables for our own use, and supply them with values too !

Study the following update code, which is now in a method called 'TestSingle_02'. Really this name would be better

as 'TestScalar_02' but then I am only human ;-)

=====================================================================================================================================

Lets now go and try out some more data types ...............

Trying 'DateTime' with our Scalar querying :

Okay then guys, lets move on. Now we need to look at a scalar value being returned from our query which is of type 'DateTime'.

We will continue to use the 'SalesOrderHeader' table, and our 'OrderHeader' class.

Let us try and find the earliest order made, and report back the actual 'DateTime' for this order.

=============================================================================================================================

As you can see from the details in the above image, this is also quite straightforward.

Now we can go on to another simple data type, that of 'int'.

Trying 'int' with our Scalar querying :

Okay then, lets do something a little different, and count the number of orders that Sales Rep. number 279 has made in

the whole of the database records to date :-

=============================================================================================================================

I have tried once again to use a named variable which reflects the origin and/or meaning of the value held within.

So 'NumSalesBy279' is our variable name.

How to use these Queried Values :

Now then, in the work we did above we did nothing more than make a suitable query and then get a value returned to us.

However, in real world coding and development we need to warp up this sort of code to populate properties of business

logic objects, or custom objects.

Also I suggest that we may have a programming need to make a bunch of STATIC members to do this, both STATIC Methods and

also STATIC properties.

=====================================================================================================================================

In the above code we still need to do some tidying as the message information is output twice - once from line 38 shown

above, and also from the new STATIC method itself - seen in the following image :-

==================================================================================================================================

You will notice in the above image that the code is for the 'OrderHeader' class itself, and we have added a STATIC Method which returns

a value for the earliest order date - well DateTime value actually.

With some thought we could actually make a whole bunch of such STATIC members and place them in each of the classes relating to

the Tables in the SQL Server database.

With some afterthought / reflection, it seems as though the above STATIC Method should be called 'EarliestOrderDate'.

Finally, for this subsection, lets see what we get when we attempt to move (successfully) the 'average' code into a new STATIC

method within the class definition for 'OrderHeader' - see below :-

=============================================================================================================================

Okay, enough of all the success with reading date and aggregated vales in from existing SQL Tables ;-)

Lets move on to another section where we learning something else new to us !

See you in the next section .......................

PHH - 19th. August 2012.


Chapter 10 - LINQ to SQL (thinking right)

Chapter 10 - LINQ to SQL (thinking right)

 Previous topic Next topic

Chapter 10 - LINQ to SQL (thinking right)

 Previous topic Next topic

The Good News is that with 'LINQ to SQL' we can by-pass a lot of the tedium (and complexity) of using ADO.NET directly.

In fact we see no signs of ADO.NET at all while using 'LINQ to SQL'.

ADO.NET is good, and it is solid, and it works well - BUT - it is not as 'Object-centric' as we require in these modern times.

Although I have used ADO.NET directly for some years now, and written myself a supporting STATIC class or two to

make my coding life in Vulcan.NET easier, I welcome the chance to try 'LINQ to SQL' to make this more 'objective'.

I say 'objective' as both 'LINQ to SQL', and also the 'Entity Framework', were created by Microsoft to allow developers

to work with objects in the code, almost from the word go. By this I mean 'go', as in as soon as the data is read in, we

are then dealing with custom and business objects, and in many ways we are doing this before the data gets read, as our

code specifies what is required, in object terms. So LINQ code is in object syntax even before a connection is made to

the database.

At the heart of this approach is the 'DataContext' class and this is dealt with specifically in the next subsection.

Here is what the modern MSDN (library) eNotes says :-

=======================================================================================================

So in my simple thinking 'DataContext' actually is 'LINQ to SQL' !!

I think it is time to move on, and go and study the full details of 'DataContext' in the following subsection .............

PHH - 22nd. 2012.


'DataContext' - at the heart

'DataContext' - at the heart

'DataContext' - at the heart

 Previous topic Next topic

So 'DataContext' is what we need to know about, in order to master 'LINQ to SQL' and as we move into

the world of 'Entity Framework 4' and beyond.

Here is more useful information from the SDK docs (or MSDN library) :-

=========================================================================================================================================

From the above statements it would appear that we need to create and have available a 'DataContext' object at all

times through the lifetime of our apps.

Since it does the housekeeping for all our data changes and updating, in all of our 'entities' (.NET objects to Tables?)

it would seem sensible to have this running in much the way as an 'Executive' operates.

Basically, we need to find out much more about 'DataContext' class , as well as the 'Entity' class,

In a lot of the subsections in these eNotes you will see test code which instantiates a ' db' or DataContext object, just

before it is used in the subsequent code.

However, this is most probably NOT The way to structure a real app., so take this into account when you check

out the test code.

If a DataContext object is to monitor at all times the data changes on properties of custom objects, the it has to be

there (in existence) all of the time the apps is making changes etc..

Constructors and Overloads - DataContext :

When we look at the MSDN library we see that we have these four overloads to look into :-

=======================================================================================================================================================

Okay, it looks as if we can instantiate with a connection string or an object instantiated from a string, BUT we need to investigate

the use of a 'Mapping Source' it would seen. This may be a lot later on, first we need to see the following about not fighting our

'DataContext' object, and leaving connection open/close for it to deal with - see below :-

========================================================================================================================================

Okay then, lets do some real coding, and get some results ...........

How do we instantiate for simple use ? :

Below is code from a working example, but PLEASE remember that we may need to instantiate right after the

application launches - as we need the object to persist for the whole application running life-cycle.

======================================================================================================

In fact in line 232 we are using a single string as input parameter, and are therefore using the second of the four overloads.

Checkout the next image where we have a STATIC method to provide our long connection string :-

==============================================================================================================================================

Now then, in some other parts of these eNotes you will see me using a second STATIC method, and one shown below

demonstrates this - we have about four such methods on my code here - for connecting to different databases - check

out the following code :-

============================================================================================================

Notice that in the above STATIC method the connection is not open for long as the 'using' command has

scope defined by its curly braces.

Line 48 therefore instantiates a 'SqlConnection' object and line 50 opens a connection if at all possible with the

string being provided.

However, when the messages are done, and removed from the screen the 'connection' object goes out of

scope and will be colosed

The reason I have such methods is simply to test and check that the connection strings work 100% before

moving on to try other new code sections.

Lets move on ......................

How do we Use the 'DataContext' object ? :

Okay then guys, lets see how we can use the 'DataContext' as a 'gateway' to our SQL database.

In the image shown below notice line 389 which instantiates a 'Products' object using the 'GetTable' method of the DataContext class.

Notice how 'Products' can then be used in LINQ syntax in lines 393 - 394 :-

============================================================================================================================================

Now the bit of advice to clarify things even more ;-) Do NOT get line 397 mixed up at all with what we are about in this short section.

The 'DateContext' property on the WPF Window is where our data binding takes place.

Now lets see the whole of the returned data set, the 'result' as bound to the DataGrid control :-

===============================================================================================================================================================================

Here is the complete XAML script for the WPF form :-

=======================================================================================================

And we get this all to happen by adding the call to the test method in the constructor of the main window as shown below :-

==========================================================

And lets move on a few more paces ...............

We can now move our instantiation of the 'DataContext' object to as high a level in our demo test app as possible.

Study the following small code snippet :-

======================================================================================================

And now see how we have adapted the original 'Test' method to use this rather than instantiating at a lower level,

which means the 'db' object goes out of scope when the method is 'done'.

========================================================================================================================

Note that re-compiling and launching the app still gives us the same data output etc..

Properties and Methods - 'DataContext' :

Now it is time to see just what members are available to us in the DataContext class.

One way is to use VS11 intellisense - see below :-

====================================================

However, I think we would be better advised to look at the MSDN library details - see below :-

============================================================================================================================================================

===========================================================================================================================================================

Don't worry to much about each and every one of these members, we will get around to trying out many of them

as we make our way (progress?) through the examples we will try out, and explore in these eNotes.

Finally, for this section, we have another useful 'Remark' from MSDN library which is different to that at the top of

this subsection - check this out CAREfully :-

==================================================================================================================================================

We have enough to think about from this section, lets go for a refreshment break, before moving on to learn

more stuff on LINQ.

See you after a cup of tea, in the next section .....................

PHH - 22nd. August 2012.


Entity Framework - where it fits

Entity Framework - where it fits

Entity Framework - where it fits

 Previous topic Next topic

===============================================================

========================================================================================================================

To be honest there is rather a lack of information on 'MappingSource' even in the MSDN library.

At this point of our learning we need to see these few eNotes from the MSDN library :-

========================================================================================================================================

=============================================================================================================================================

I think we need to leave 'Entities for now, and go and research the DataContext class, and its use, as thoroughly as possible.

PHH - 22nd. August 2012.


Reading Data

Reading Data

Reading Data

 Previous topic Next topic

Okay then folks, lets make a few more new steps towards understanding 'LINQ to SQL'.

In the earlier subsections you may have seen me do the following :-

==================================================================================================================================

But in fact we need a 'DataContext' object instantiating right at the start of our SQL and data-centric application.

We also could do with having all of our required Tables/Objects available and tracked right from the start too.

So here is my improved way of doing things.

First we make our own class based on the 'DataContext' type - checkout below :-

==============================================================================================================

Notice that we have done all five of our existing mapping classes, these are now all public properties.

Also, when we instantiate we need the constructor to take a correct connection string for our SQL Server and database.

We can now start our app as follows - check it carefully :-

===========================================================================================================

So line number 37 will accept the connection string and set-up our own 'DataContext' class object called 'odc' in the

above code.

Now as long as we adjust the code within the Test method accordingly, we should get things to work just as before.

Let us see what our Test method now looks like - see below :-

================================================================================================================

Yes, we do need a few changes, but these are easy to make.

The input parameter is now of type 'OurDatCont' and not 'DataContext' and the collection referred to in line 416 is now a

property of the 'odc' object, so 'Products' has become 'odc.Products'.

And that is that. So we could go on through the logic of our app coding and use and change Orders, Products, Customers,

Addresses, and OrderItems, and any changes would be tracked for us by our own DataContext object 'odc'.

You will see in a few subsections time how any changes on the collection 'entity' objects are only copied to a persistent

state in the back-end server when method 'SubmitChanges()' is called on the 'odc' object.

If we study the image beneath, we see this method in the drop list from intellisense.

================================================================================================================================================================

It is obvious from the above detail that changes are forced to the whole database, and not individual tables.

Also in the above image details we see the collection properties of Orders, Products and SalesItems, also listed.

Reading - More Complex Situations :

Okay then guys, if we have this right, and have our DataContext inheriting 'type' available for the whole time the app is running,

with associations to all of our mapped objects, then we ought to be able to use multiple tables in our queries within need to

do anything more than what we have done already.

Let us try out a 'Join' using two different tables - study the details below :-

=====================================================================================================================================

Well, in the above image 'odc' is passed in as a parameter and then all we need do is use it to specify both of the

tables required in our query. See lines 115 and 116.

The next image shows the data output from the query, as displayed in the WPF 'DataGrid' control - see below :-

================================================================================================================================================

PHH - 22nd. August 2012.


Managing Data - 'Modifying'

Managing Data - 'Modifying'

Managing Data - 'Modifying'

 Previous topic Next topic

We need to be aware that :-

The acronym “CRUD” means Create, Read, Update, and Delete. These are the fundamental

operations that a storage system provides. They correspond to the SQL statements INSERT,

SELECT, UPDATE, and DELETE, respectively.

Using LINQ the reading of data is usually done in an indirect manner. So we are left with 'CUD'.

Adding (INSET), Changing (UPDATE), and Removing (DELETE) - we can think of 'Modifying' our

database as being any or all of these three things.

Basically we need to find out the first 'level' of approach to being able to carry out CUD using LINQ syntax.

============================================================================

Like a lot of things, this topic seems simple and straightforward enough - BUT !!!

To get going with reading in proper SQL data we usually turn to a fully developed database, as

this is best for demonstration purposes, and a LOT of effort has gone into the correct design, using

Primary Keys, Foreign Keys and much more.

However, these fully developed 'demo' DBs are not necessarily best for doing work on CUD.

To explore CUD (Create, Update, and Delete) we will first use our very simple database (DB) which we

have entitled 'OurLinqTest13'.

In the following image we see the state of this single tabled DB as it is at the moment. Check it out :-

========================================================================================================================================

In the following few subsections we will explore how to Add, Change, and Remove data items in rows in the SQL tables

using LINQ syntax and general approach.

While we enjoy ourselves learning, and getting good results, we also need to keep in mind that we are ultimately aiming

at using an 'Entity' approach - the Entity Framework (4 and above) is a Microsoft product and one which brings 'objects'

to the developer straight from the data source.

When we move to using Entities fully, and/or correctly, we will need to handle a whole bunch of interrelated Tables and Views

in our SQL databases. This will have implications on how we set-up and use our own custom / business objects, and also

vice versa to some degree or another.

So PLEASE remember this as we explore how to take single tables and do CRUD and CUD on these.

I think that having read a few texts on LINQ that we need to take a 'step at a time' so that we can build up out LINQ skills

and knowledge - BUT - at least being aware or where we are headed.

If we look at the next small image - from the eBook by Pialorsi and Russo, we see that 240 pages in (chapter 8 of 19) we

get to Entities and data Modelling :-

==============================================================

But for now, since LINQ is a supporting layer to EF4, let us test and try all we can in LINQ with single tables, before we get

any more complex.

If we try to do too much at once then we will get confused, and not know what we are about, or why things work the way

they do.

Lets move on and make some progress ..................

PHH - 20th. August 2012.


Adding Rows - INSERT

Adding Rows - INSERT

Adding Rows - INSERT

 Previous topic Next topic

Okay then guys, let us make a start to putting new data records into existing Tables of a SQL Server

database.

We will start simple, in that we will attempt to add a row to an existing Table, one which has been

designed previously. And, we will kepp away from messing up large and intact sample databases.

What we need is a test and demo DB.

=============================================================================

Now then folks, we need to write a small bit of test code to allow us to try and add a new 'OurCustomer' row

to the existing database - seen in the introductory section to "Managing Data - 'Modifying' ".

The following image shows how helpful the intellisense is in C#, to 'guiding our hand' - so to speak.

==========================================================================================

And as we select and use the properties (fields in the SQL DB rows) the drop list shrinks - see below :-

========================================================================================================

Remember that in 'our' customer form of a class we have a mapping of 'Region' to 'State' as seen below :-

[ .. yes, I am now aware of the fact that 'db' in line 15 is incorrect and will cause us grief - more on that later .. ]

================================================================================================

Lines 24 and 25 above are where the 'mapping' takes place - so the Table has a 'Region' column and

the .NET class has a 'State' property.

Now lets look at what our fully developed 'testing' code section looks like, before we try it out 'for real'.

[ .. note that it still needs another (and important) line in position 149 .. ]

=============================================================================================================================

Notice in the above image that we have added a TRY / CATCH as hopefully being helpful to us ;-)

Okay then, lets run our code and see what we get - fingers crossed :-

=========================================================================================================================================================

Oh! I told you that this simple stuff is 'never easy' ;-)

I can't see that we have any parameter options, so it must be some sort of a condition 'imposed' on us when

we are using the DataContext 'system' perhaps - Tables MUST have PKs ! ?.

For now let us change our DB in Management Studio to see if we can force the issue - Oh! and change settings

in our class too (see a few images beneath for the Column attributes changes ... line 18 ).

Yep! one of those MS moments, we have to DROP the table and re-enter the design, AND the data. Now you see why

I chose a simple one Table DB of our own ;-)

So less than 5 minutes later we have the following in our MS 'shell' :-

============================================================================================================================================

So what do we get now when we compile and run our app ?

Checkout the following image :-

============================================================================================================================

[ .. notice that line 149 has been added, that which forces the changes to be persisted to the back-end data source .. ]

Well, yet another set-back, but thankfully the Try/Catch/Finally code structure comes to hand.

I have to confess that at first I was misled and thought that 'db' was referring to our code lines 135/136 relating to data context

and meaning 'data base' (db), when in fact it was nothing to do with this :(

See below for the 'gotcha' situation to be revealed :-

======================================================================

Oh! "nasty one" ! ... so the 'db' in the error message box had nothing to do with 'db' in line 135 when we were

coding the DataContext 'thingy' !!! Well, we live and learn - the hard way.

It was simply due to a typo by yours truly :-)

Well, after that 'letting of blood' we can at least compile and run our code - and see some success ;-)

Study the MS 'shell' details below - these represent the state of our trial DB after the demo app has been

run once, and once only :-

========================================================================================================================================

As you can see we now have a sixth row in our returned data set, and 'CustomerID' is of value 'c013'.

So lets do that again for good measure, compile and run that is. Check this out :-

=======================================================================================

Oh! silly me, well of course, we can't do it a second time as the PK value already exists.

However, we could re-try this if first we removed, or deleted the row.

But first I will change the PK value to 'c015' and retry - so here is the result of such an action :-

=====================================================================

So maybe we had better move on to the next subsection and see how we can DELETE either

one, or both of these.

See you in the next subsection ...................

PHH - 20th. August 2012.


Removing Rows - DELETE

Removing Rows - DELETE

Removing Rows - DELETE

 Previous topic Next topic

Well folks, with a nice slice of luck we may be able to get this subsection to 'work' easier than

the previous one on 'Adding' with INSERT.

By the way, in all these sections on Add, Remove and Change, we need to have the .NET code

line for the appropriate method to be run, included in the 'MainWindow' constructor - see below :-

===================================================================

We will first work on the identity of 'c015' before we try 'c013'.

Here is the new code in our testing method :-

===========================================================================================================================

Oh! well, the following results make sense, now that I think about what I am doing ;-)

Take a look at what we got at compile and run time :-

=================================================================================================================================

Okay, I see a few things we need to correct and improve, including some text and label output.

The BIG obvious problem is that before we can remove or DELETE a Table row, we need to identify it - NOT make

a new object with the same property values. That was OK for adding !

So how about the following as a second attempt at 'removing' ?

First you see that we identify the correct and existing row by LINQ code object identification, then and only then,

will we attempt to delete it - check this out :-

=====================================================================================================================================

Yep! I think this has worked OK, but nothing is obvious from our .NET code as yet. We need to improve that.

All I can see, and tell you of, is that no error messages were displayed, AND, that the re-run (or executed) query in

MS gave 6 rows and none with identity 'c015'.

Here is the new code to try and remove row with PK value of 'c013' - check it out thoroughly :-

==============================================================================================================================

I have just re-compiled and run the demo app and things are looking up ;-)

The output seems to suggest all was 100% well and correct.

This is what I got at runtime, over the re-executed SQL query in MS :-

===========================================================================================

That looks fine, and it teaches us a good lesson I feel.

In all this 'stuff' with LINQ it is just too easy to focus on the code and syntax and forget the real meaning

of it all.

We MUST keep thinking in terms of objects other wise we will keep making similar mistakes to the one

we saw me make above.

Before we can 'remove' an object we first must identify it, and that means looking at the database itself.

This also means we have saved ourselves some further grief when we come to changing, editing, or

what is termed UPDATE in SQL parlance.

In the next subsection we need to identify the object to be changed, get a copy of this, and then make the

changes. We then write those changes back ........................

See you in the next section where we already know what to do ;-)

PHH - 20th. August 2012.


Changing Rows - UPDATE

Changing Rows - UPDATE

Changing Rows - UPDATE

 Previous topic Next topic

Okay guys, the last subsection on 'DELETE' has greatly helped us in this section already.

We found that we must identify the row, and hence DB object, before we make any changes

and then re-write back to the SQL Table.

Firstly I will re-run the test method which adds in the row with ID equal to 'c015' - see below :-

[ .. just so we have something suitable to work with .. ]

=====================================================================

Now we can go look for a suitable Extension method - like .DeleteOnSubmit, and .InsertOnSubmit in

the drop list from intellisense - see below :-

====================================================================

As you can see in the image above, there is no entry for 'Update', so that would suggest that there

is another way of doing things.

Also, this situation of the missing '.UpdateOnSubmit' method would also indicate that we can see a

lot more about what is really happening than perhaps we thought we did.

First of all, see the following image in which we find the target row / object and then make changes directly

to the object properties, and then simply request that changes are submitted.

Check this out for yourselves - notice line 193 in particular :-

===============================================================================================================================================

Before we get into a deep discussion on what is going on, and why etc., let us look at the following image

of the output and check out that all changes have taken place, and data has been updated or changed :-

========================================================================

Okay then we seem to have full 100% success on the 'change' front.

So it would appear that any object we have associated with the 'DataContext' is part of an underlying system of checking on

whether changes take place, or not, to properties and other registered items.

It would appear that once we request via the 'SubmitChanges' method, that changes on the 'db' (database) object of type DataContext

are to be carried out, ALL, existing changes are 'forced' through if at all possible.

This gives me a good (possibly great) idea, one we need to check in the very next sub-section.

See you there when we try to do everything at once ........................... ;-)

PHH - 20th. August 2012.


Batch Process - all changes at once !?

Batch Process - all changes at once !?

 Previous topic Next topic

Batch Process - all changes at once !?

 Previous topic Next topic

Okay then, what is my good, bad, or just stupid idea ?

Well, I wish to try out a test code method which runs code to add a new row (object), then remove and existing

one (a different row), and also read, identify and change a third row, before we force the changes to occur.

In fact we can make it even better than this as we can display a 'MessageBox' before we force the changes, and

at that point go and use MS to check what is in the SQL Table.

So we can do a 'before and after' thing with our DB, just to see what is going on.

Well, lets get to it and make some suitable .NET code.

Firstly lets change the method call to the test code - see below :-

============================================================

And now let us look through this method, with code to try and achieve three separate actions on the

same Table within the database.

Basically in the following image you see code which takes parts form each of the other test methods,

BUT, with one BIG difference, we have only one call to 'submit changes' and that is on line 233.

Study all the following code CAREFULLY ! - see below :-

=======================================================================================================================================

And now to try this out at runtime ;-)

Here is the first message, and the immediately updated version of the SQL Table via the MS 'shell' :-

==============================================================================

As you can work out, in the above image, none of the three changes have been made as yet and

row with ID 'c015' still exists, row three has not been edited, and the new entry with ID 'c077' is

still missing.

And now to move on to the state of things when the second message is displayed.

Obviously, I had to force the 'Execute' once more in MS to get the up to date returned data set.

Checkout all the three sets of changes for yourself :-

=======================================================================================

The moral of the story is - you can make as many code changes as you like - BUT - if

you don't force these to be made in the database (back-end data source) by using and running

the 'SubmitChanges' extension method then you will not get any persistent changes.

Enough for one day I feel.

Although the research and experimentation on 'Changes' to data - 'Modifying' if you prefer - has

gone rather slowly, it is an important thing to get right, and understand as much as possible.

My current feelings, after ploughing my way through this, is that it is NOT as complicated as I

first thought it was.

The text books I used can't show and experiment as we can when doing eNotes, so it was a bit of

an unnecessary struggle I feel.

Still, I will so much more knowledgeable to start again tomorrow ;-)

See you in the morning, early ! ......................

PHH - 20th. August 2012.


'Direct Querying' with LINQ

'Direct Querying' with LINQ

'Direct Querying' with LINQ

 Previous topic Next topic

There are times when we may need, or wish, to send SQL query statements directly to the back-end database.

This is often termed a 'pass through mechanism', simply because the original query is more or less just passed

on by the LINQ system, directly to the DB.

There are two similar methods we need to know about, 'Execute Query' and 'Execute Command'.

Lets take these in turn and study them in detail. First the 'Query' form ...........

Execute Query :

Here is what the modern MSDN documentation has to say - note the 4.5 .NET framework.

===================================================================================================================================================

It is really rather important to know exactly what we will get back from any query of this format.

If you run at it with your head down, in order to get some quick results, you will come to grief - Yep! how do I know ? ;-0))

=============================================================

So if we get back something which can be enumerated, then we need to think on that before we write our code.

First lets look at another section of the SDK documentation - see image shown below :-

[ .. note that 'Copy' in blue is a dead icon ! .. ]

=======================================================================================================

I am not quite sure of the meaning of the '@' symbol but I can get queries to work both with and without it.

So lets checkout how to get some results first.

By now the ideas in the following code image ought to be reasonably familiar.

We are just trying to get back, returned as a data set, the complete list of customer rows from the SQL table.

Take note of line 125 as this will have a variation or two shown later on in this subsection :-

===============================================================================================================================================================

In fact there is one message box detail which has not been shown, so lets look at it now to checkout the returned data type :-

We must not be tempted to use this object as a table objects, as in days of yore !

Yes, it feels to me as if DataTables and DataSets are a thing of the past !! We now live in a world of 'Collections', 'Enumerations'

and the 'Disconnected Model'. We just have to accept this and get on with things ;-)

Now lets study the '@' alternative - does ' @ ' mean NOT escaped as a sequence ? since I had to drop the second slashes.

====================================================================================================================

And to qualify what I thought was the case above with escape sequence etc., here is a 'StackOverflow' posting :-

The @ symbol serves 2 purposes in C#:

The first is that it allows you to use a reserved keyword as a variable like this:

int @int = 15;

The second option lets you specify a string without having to escape any characters.

For instance the '\' character is an escape character so typically you would need to do this:

var myString = "c:\\myfolder\\myfile.txt"

alternatively you can do this:

var myString = @"c:\myFolder\myfile.txt"

So for Vulcan.NET guys we have the reverse logic on using string literals with the ' e' before our strings.

Example is :- e"c:\\myfolder\\myfile.txt"

Okay then, we also need to run our eyes over the extra stuff from the SDK docs :-

======================================================================================================================================

Okay then, a bit heavy for this late afternoon session - BUT - to me it sounds as if it is not as pass-through as I first thought.

Arhh ! yes, but if we are using our defined 'Customer' class then it is not surprising really. Sounds as though we need some

more trial and experience - now that we can get some results !

Above I have used only one of the overloads - below is the full set - well two actually :-

=======================================================================================================================================================

Let us now move on to see what we can get to happen on our

Some Possible Variations :

Right then, lets try a scalar return value of type ' int '. Check this out below :-

========================================================================================================================================================

However, if we look at the above details it is not clear as to whether ' c ' is a string type or a numeric.

Let us change the code to check this for ourselves - see the changes below :-

========================================================================================================================================================

Yep! to my mind ' c ' is certainly numeric - as 2*6 certainly does equal 12 !!

Now then, lets 'push the boat out' and go for a filter condition - check this out :-

============================================================================================================================================

Okay then, we certainly are managing to get some useful and positive results.

Time to move on, we can now look at the 'Command' for of this pass-through approach, when no result is expected.

Execute Command :

======================================================================================================================================================

================================================================================================================================================

Explain this section correctly in the morning when I am fresh once again ;-)

=====================================================================

====================================================================================================================================

Wrong way around - re-try ! NO - its okay if we read it correctly ;-)

====================================================================================================================================

======================================================================

====================================================================================================================================

===========================================================================

====================================================================================================================================

Using the New Connection - Application-Wide approach :

PHH - 21st. August 2012.


Chapter 11 - LINQ to Objects (2)

Chapter 11 - LINQ to Objects (2)

 Previous topic Next topic

Chapter 11 - LINQ to Objects (2)

 Previous topic Next topic

PHH - 16th. August 2012.


Chapter 12 - LINQ to 'Entities' - "Entity SQL"

Chapter 12 - LINQ to 'Entities' - "Entity SQL"

Chapter 12 - LINQ to 'Entities' - "Entity SQL"

 Previous topic Next topic

Recently (November 2016), I have seen 'LINQ to Entities' (L2E) referred to as "Entity SQL".

It seems as though we need to be flexible in what we read and interpret along the 'LINQ' side

of things, as far as Entities and their framework are concerned.

=====================================================================

Once again, as with 'L2S', the success of the technology is all on the 'mapping'.

If the mapping is done right then the movement of data back and forth between the relational database

and the .NET class entities will work 100% and also 'smoothly'.

The .NET class object that comes in between the 'R' and the 'O' of our "ORM" is know to us as an object

of type 'DbContext' (said database context).

If you read and studied the sub-section on 'L2S' you will remember this pivotal object similar in many ways,

and of type 'DataContext', which is said 'data context'.

So in going from L2S to 'Entity SQL' we have moved from 'data' to 'database' in the naming of our central

'mapping' object class.

Generally, this change will be reflected in the complexity of the Entities - the data has become much more

structured.

So not just the data (single Table/) is mapped by 'DbContext' but quite often an Entity class has data from

many Tables, automatically brought over by the aid of our more complex mapping.

Oh! and by the way 'complex' does NOT have to mean complicated.

We standard coder guys should be easily able to handle Entity SQL and LINQ, and all that is involved with

the now popular 'Code First' approach to designing, creating, and maintaining a back-end database via .NET

object classes.

The 'DbContext' seems to do much more for us than even the good old DataContext did.

Oh! and for guys that are not MS SQL Server folks, then L2E can support many more makes of Server.

Here are some possibilities fro now and definitely the newer version of EF (Core?/7/) to come :-

==================================================

PHH - 14th. 2012.


Approach to coding used here in this section

Approach to coding used here in this section

Approach to coding used here in this section

 Previous topic Next topic

PHH - 9th. December 2016.


Database First

Database First

Database First

 Previous topic Next topic

https://www.codeproject.com/Articles/1012100/Use-EF-Power-Tool-to-generate-EF-POCO-classes

============================================================================================================================================

====================================================================================================================================================

=========================================================================================================================

PHH - 9th. December 2016.


Model First

Model First

Model First

 Previous topic Next topic

I have included some information in this section just because I have come across bits and pieces as I have

done my research.

It would appear that for Entity Framework 7, (now to be "EF Core" or, "Entity Core", or a similar title), that this older 'Model'

way of doing things is either degraded, or completely out of fashion.

Myself, I feel that 'Code First' is the way to go, and I like it a lot ;-0)

And it does not really need any special tools, just the assemblies to add into the References section of our solutions.

===================================================

========================================================================================================================================

=================================================================================================================================================================

=================================================================================================================================

PHH - 9th. December 2016.


Code First

Code First

Code First

 Previous topic Next topic

This is my preferred approach to Entity Framework 'stuff' and I have successfully used it with version 6

of the framework.

It sounds from what I can research and find on the web that 'Code First' is to be a big player in versions

of EF to come - like 'EF Core' , as '7' seems to be deg-regraded, or pushed to one side.

'Code First' will certainly be there right from the start, in any new version of EF to come.

So lets get to it and see what can be done in the latest (existing) version 6.13 of the framework.

=======================================================

==========================================================================================================

====================================================================================================

================================================================================================================

==================================================================

===================================================================================

=================================================================================================================================================

=================================================

=================================================================================

The 'EF6' application as shown in Cologne April 2015 :-

=============================================================================================

===================================================================================

PHH - 9th. December 2016.


'Mapping' - the EF way

'Mapping' - the EF way

'Mapping' - the EF way

Previous topic Next topic

To put 'O/RM' in place (object to relational mapping) for Entities, we need a central linking class of object.

In the framework we can acquire via NuGet we have a class called 'DbContext', said or thought of as 'database

context'.

Remember that for 'L2S' we had a 'data context' (DataContext) class to act as the central 'pivot' to our mapping.

https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext%28v=vs.113%29.aspx?f=255&MSPPError=-2147217396

Here is what part of the MSDN web notes have to say :-

==============================================================================================================

And here is just one constructor overload which I use in my test application - the one prepared for Cologne 2015 :-

===========================================================================================================================

If we look at part of the "initializing" code in my test application we can see line 139 shown below :-

=======================================================================================

Yes, we use an overload on the constructor which takes a standard 'string' type.

Lets try to display this when we run the application :-

====================================================================================================

Notice in the above image (line 146) that we appear to have a property on the 'DbContext' object which is

named "Database".

And here is the STATIC method I created to provide a suitable string for connection :-

======================================================================================

Line 110, 112, and 117 are the most important in many ways, as they allow us to point at the right data file,

DB instance, as well as the Catalog required.

Here is an alternative idea :-

========================================================================================================

Lets now look at the three Properties of the 'DbContext' class - checkout the familiar one of 'Database' :-

=============================================================================================================================

Don't get 'Configuration' mixed up with the Configurations collection we will create as a Property of the DbModelBuilder

class we will see in action below.

We will in fact come to use these other 'Configuations' a lot in our code - it allows us to drop using Attributes and move

the detailed specification of columns and their data, type and restrictions, from within the Business Class - which is

more intuitive to .NET coders I feel.

Lets now look at my sample sub-classed 'DbContext' class from the working application - lookout for some of the above :-

=====================================================================================================================

Yes, when studying the above code we see we need to discuss DbModelBuilder, DbSet, and Configurations.

Before we go any further lets look at one of my working examples of a 'Configuration' :-

[ .. lines 79 through 81 hold the detail for 'AttendeeConfiguration' .. ]

===================================================================================================================

Above, it is not hard to see that this sort of information was provided by Attributes in the 'L2S' approach shown in

earlier sections.

Here is a further working example, which shows more wide ranging (and different) property definitions :-

==========================================================================================================================================

Lines 123, 125, and 126, are particularly interesting.

Naming 'convention' :

It apparently is 'convention' to call our configurations by the Class name with 'Configuration' concatenated.

Although we can change this, it just makes more work and gives us more places to maintain code etc..

Here is the Attendee class definition which goes with the 'AttendeeConfiguration' :-

[ .. note that we have no Attributes, anywhere - looks just like those classes I created for standard WPF data binding .. ]

=========================================================================================

Fields and Properties are used and defined as in my work on WPF data binding, delivered to the

Cologne Conference in 2015 & 2016.

However, the 'virtual' properties on lines 157 and 158 are interesting, as well as being new and different.

Now lets look at a bit more detail - that which was previously collapsed in the above image :-

==========================================================================================================

The Property Change notification is pretty standard stuff for the way I do data binding with WPF - see my other

eNotes to follow this through.

PHH - 9th. December 2016.


more about DbContext

more about DbContext

more about DbContext

 Previous topic Next topic

PHH - 10th. December 2016.


Creating & re-creating the database

Creating & re-creating the database

Creating & re-creating the database

 Previous topic Next topic

PHH - 10th. December 2016.


Seeding the Data - Populating the Tables

Seeding the Data - Populating the Tables

Seeding the Data - Populating the Tables

 Previous topic Next topic

===================================================================================

===========================================================================================================

==================================================================================================================================

PHH - 9th. December 2016.


Accessing the Table data

Accessing the Table data

Accessing the Table data

 Previous topic Next topic

==================================

============================================================================================================================

================================================================================================================

==================================================================================================

=====================================================================================

PHH - 9th. December 2016.


Making on-screen data changes

Making on-screen data changes

Making on-screen data changes

 Previous topic Next topic

================================================================================================================================================================

================================================================================================================================================================

========================================================================================

PHH - 9th. December 2016.


Persisting the changes to back-end database

Persisting the changes to back-end database

Persisting the changes to back-end database

 Previous topic Next topic

========================================================================================

================================================================================================================================================================

==========================================================

========================================================================================================================

====================================================================================

=======================================================================

PHH - 9th. December 2016.


Chapter 13 - LINQ to SQL - advanced

Chapter 13 - LINQ to SQL - advanced

Chapter 13 - LINQ to SQL - advanced

 Previous topic Next topic

Introduction to Advanced LINQ to SQL :

Okay then guys, why this section ?

Well, at first when we come to LINQ the examples in the eBooks and other learning material seem easy to follow,

and they work okay.

However, it is only when we start to code up for ourselves real life examples, that we see that we often need to go

MUCH further than we are shown in the learning texts.

Personally, while doing the 'Data Logging' application, I have hit many places where I have found it very difficult to

find suitable examples of LINQ query syntax, that which I could copy and adapt - as you do ;-0)

So for this reason alone, I am going to include all those extra parts and bits, and experiments, here in chapter 13.

[ At lot of readers may also realise that I have a few years experience with using SQL from Management Studio, and so

I have gotten used to making more complex, and very useful, SQL queries, on large and complex databases, so I don't

wish to go backwards when I come to start using LINQ queries. ]

I hope it helps you as much as it has me !

PHH - 10 th. December 2012.

========================================================================================

Let us first remind ourselves of this :-

======================================================================================================================

So what this means is that when we use a 'DataContext' object we are doing 'LINQ to SQL'.

As simple as that !

So one of my real live application, 'typical' methods, looks like the following :-

=============================================================================================================

Yes, we see lots of such sample code sections in the books, eBooks, and web articles, but often we

are shown just the simplest of cases, dealing with the simplest of SQL queries.

And even then the 'where' clause has two conditions, when often the text examples are limited to one

as shown below :-

=======================================

Yes, I am very much in favour of simple examples - BUT - we then need to extend these to cover all the

likely cases we are to get in real life scenarios, and for real applications. This means having samples and

examples which are as complex as the SQL query scripts we used to write in Management Studio, and

then pass to ADO.NET methods as text strings.

Sending scripts directly - a 'cop out' !! :

The result of too many simple examples, and not enough (or any) real or complex ones, means that often,

out of pure desperation, we resort to sending the same old scripts directly from our link connection.

Here is a perfect example of what I did to get my application up and running - check this out :-

=================================================================================================================

You can see in the above image that the SQL query went to the Server as a text string from my code, rather than

the query being coded and converted into a query sting by the LINQ to SQL system.

Yes, that is right, whatever happens in the code and the runtime system etc., etc., the result is always a string being

sent to the SQL Server. We need to remember that this is how SQL Servers work - queries and commands (for

everything) are sent as text strings.

Usually, this is done by ADO.NET, by us (as we used to code things) or by LINQ code being converted for us into

ADO.NET stuff.

If Microsoft are strongly advising us to use LINQ query syntax at all times, then we need to find out how to do all

the things we used to do in our SQL scripts.

For guys knowing SQL they we recognise that the above script (shown in lines 245-253) is a CTE, or Common

Table Expression. So this is one thing we will need to discover how to code up in C#.

Sub-queries, and correlated sub-queries are other things that we will need to find out how to express in LINQ

query syntax - or at least which 'bits' we need to steer around for the current version of C#.

Let us now move on to the sub-sections of this chapter to see what we can do in a more advanced way with

the LINQ query syntax available to us now - version 5.0 of C#.

See you there ................

PHH - 8th. December 2012.


Single Table use & data returned

Single Table use & data returned

Single Table use & data returned

 Previous topic Next topic

Okay then, one thing we need to get straight is that we need to have at least one Table available

to us when we are using LINQ to SQL.

Below is my real (but simple) example from the introduction to this chapter, and line 2177 effectively

'points' to the Table that we will use in the code for the query.

We can't say that this line opens the Table, as remember, the action only happens the very first time we use

the 'query' variable - as seen in the code shown below :-

=============================================================================================================

So it is at line 2182 that the connection is opened to the SQL database, and the query script sent from the

code itself. Here we are using the Table mapped when we coded our business class called 'Sensor'.

It is customary, and very sensible, to use the same name as the required Table, within the name of our class. And

usually, we have 'only' the same name as the Table because we use a 'one to one' mapping - but it does not have

to be like that!

Below we have a common scenario, where the mapping is direct and complete - a class called 'Sensor'

and a Table of the same name, and all fields / properties are mapped 1 to 1. Note lines 36 & 37 which

make the class to Table connection / mapping :-

========================================================================================

So if you get the hang of what is going on, you will see that we could define another class for our

project and call it 'SensorShort' in which we code up just a few of the possible columns available

to us in the Sensor SQL Table. Below shows what we have to chose from :-

=============================================

So let us see the code for two extra classes mapped to Sensor - that of 'Short' and 'VeryShort'.

Checkout the following code :-

=========================================================================================================================================================================

Notice that lines 143 and 102 show that the actual SQL Table used for the mapping, is that of 'Sensor'.

Getting things straight - 'Tables' :

It is very important that we get things straight in our minds as to what the line means which is

effectively the Table declaration.

In the line we saw earlier (within the query section) - a part of which is shown again below - we need to more fully

explain what the line 2177 actually means - check this out first :-

============================================================================================================

In line 2177 we are instantiating a 'Table' object based on our custom class called 'Sensor', and this

is done by the system getting the parts of the SQL table mapped to - within that class.

So if we have a reduced set of columns (as in 'SensorVeryShort' ) then the coded table resulting, will be reduced too.

We have chosen to call the 'Table<T>' object 'Sensors' and that would become 'SensorsVeryShort' in the

further example we are discussing here.

NOTE - there is nothing in line 2177 itself, which suggests the SQL table being used is that called 'Sensor'.

That is all done in the mapping within the class definition, and ONLY the class mapping.

If we choose inappropriate 'naming' then we can make ourselves VERY confused indeed, so take care !!

'Tables and Tables' :

What does this confusing sub-heading mean ?

Well, it is quite simple really. We have SQL objects called tables, and we have .NET code objects of the

'Table<T>' class, which we most often call tables as well.

In my real life example (Data Logging app.) the SQL Tables are shown below :-

======================================

However, as we have seen previously, it is possible for me to have three different 'flavours' (or types) of coded

table depending on whether we use 'Sensor', 'SensorShort', or indeed 'SensorVeryShort'.

So to clarify some of these remarks, lets look at the following image where code has been added to give

us access to the collection of 'Short' sensor details - study this CAREFULLY !!! :-

============================================================================================================

Notice that we can use 'ShortSensors' as the name for our table of 'SensorShort' items. However we MUST

use exactly 'SensorShort' in the code of line 2186, 2189, and 2184 simply because this is the class name used

when we defined the class.

If you choose your names with CARE and THOUGHT, then future coding and maintenance coding will be easier,

and will cause you to make fewer mistakes.

My suggestion is that for any class which accesses a SQL Table, then the full name of that Table is included in the

class name. In extreme cases I would go for a shorted, or abbreviated, form of the Table name.

So What are the Results ? :

When we ask a query with LINQ, we get back an IEnumerable collection of objects. If we do not select the

columns / properties, then we get back a bunch of objects of the type for which we opened up the Table.

So for the following query code we will get back 'SensorVeryShort' objects, as items within our collection.

===========================================================================================================

This then means we return from the STATIC method a generic list of 'SensorVeryShort' objects. But remember,

this is because in line 2205 we are selecting the whole of the row, or each column value from the Table which

maps to a property in the class used.

Changing what data is returned :

As well as defining classes which have fewer properties than the SQL Table has columns, we can further

reduce the returned data by 'selecting' fewer fields than the table we instantiate.

To see what I mean, view the following code and in particular the line 2217, which instead of choosing the whole

row (or object) as 's', now only chooses the 'Desicription' column / field. This means that we get a single

sting value for each of the table rows in the SQL database.

Checkout the following image details :-

============================================================================================================

This static method shown above can be used as shown in the next image - see below :-

=============================================================================================================

Basically, we can consider the 'select' clause of the query statement to be that which determines the type of

objects which are returned from the SQL Server.

It is either the same type of object as the one used to instantiate the 'Table<T>', or one with fewer properties.

*** Note ***

I am ignoring the possibility of creating extra 'calculated' fields, as once we can handle fewer fields, we can then

also handle more - its the same issue in reality!

He is the example of the first case, where the type is implied - check this out :-

=========================================================================

In the above case we get a collection of objects of type 'Sensor' - or something VERY similar! However, we can

vary this quite a lot. (We will see just what class we have a little later on - just below.)

With the inclusion of LINQ technology into the C# compiler, we got the addition of the 'anonymous' type.

Yes, we can actually declare a new object which is of a previously undetermined type. Sounds crazy,

but it does make some sense.

Let us take a careful look at an example of this :-

============================================================================================================

In the above image study in particular, line 2193. This is the syntax for creating a new object of type unknown.

We call such an unknown type an 'anonymous' type. We have done this in the code above, simply because in the

rest of the app coding I do not have a defined class with the three properties equivalent to 'GPS_details', 'IsOperational',

and 'Name'.

Notice that we have to 'wrap these up' if we are to return them from the method, since in the method signature we

need to define a return type, so line 2186 has the Object array wrapper type used.

To prove this does work study the following details shown below :-

============================================================================================================================

Once we have our returned object data in this form of collection we can do with it as we please.

However, I suggest that we are better to define a specific class of our own, and use that - it seems that this is

more likely to be the case if we think ahead and design our project / solution, rather than coding it it on the fly,

as we go along.

So what happens if we type to force a use of our own class of 'Sensor' ? Take a look at the next image :-

================================================================================================================================

Okay, this makes sense, we have been saying for quite some time, and in previous sections, that the returned

data from a query with LINQ produces a collection of IEnumerable type.

So because our class has not as yet got the required 'parts', or members, we get an error - the properties are one thing, the

'IEnumerable' interface requirement is another.

Oh! I see, the class which is used for the 'new' statement must be a collection and not the custom object class.

So if we were to do this ourselves, instead of using 'anonymous' types, we need something like a 'mySensors' class, in

which we implement the required interfaces.

Checkout these following two images, with details from the SDK documentation on the interfaces we require :-

=================================================================================================================

and also the following too :-

=================================================================================================================================

So if we are to use any of our own classes as 'containers' for returned data, they must obey the IEnumerable 'rules'!

However, it is possible to use the LINQ code syntax without this, as I have been getting lots of success, over weeks now,

and have not made any my classes implement the above interface.

I suggest it is one of those cases where if we are smart we let the system work for us, and just make sure we 'cast' correctly at

appropriate times.

But. to show that I am not running away from these issues, we will look in more detail at what we can do, in a later subsection.

For now lets summarise what we have done in this current subsection and then move on.

Summary :

Self Join - joining one table to itself !? :

This is a well know and well used scenario in the world of SQL Server guys, and we will cover the topic in a separate subsection.

Look out for details on this interesting topic.

PHH - 8th. December 2012.


Multiple Table use

Multiple Table use

Multiple Table use

 Previous topic Next topic

Okay then guys, anyone knows that if we are to use SQL databases correctly we MUST normalise

our data, and that simply means when we come to getting back data to business queries, we need

to de-normalise very frequently.

Since normalisation is all about having an item of data (or information) in the database only once, then

this above also means we frequently need to use more than one Table in our querying.

On top of using multiple tables, we also need to 'join' them so that data from one table is connected to the

correct data from another table. And so on.

To get us going on this topic, let us view below the query text required in Management Studio (MS) for one

of the common queries needed in the Data Logging app I am currently developing :-

===========================================================================================================

In the MS query pane shown above we see that we are using three different tables, and this text query may be

simplified to be as shown in the next image :-

===========================================================================================================

So it would seem that the first question we should be asking is how do we code this in .NET syntax (using C# for now)

so that this same query works for us in LINQ to SQL.

Well, I think I have coded it as required, and the test output seems to be as required - for the first 13 rows returned.

Checkout the following image details CAREFULLY ! :-

================================================================================================================================

As you can see in the above image we need to instantiate three different Table objects, each from a different

class of custom object.

Once we have these tables we can use their variable names in our query code syntax.

However, we did not show that we first needed to instantiate a 'DataContext' object as seen below :-

======================================================================================================

In many ways the code shown in the full query one image above, is not very surprising, and it looks very familiar

to SQL guys, apart from the SELECT statement being last in the order of the query clauses ;-)

Euphoria is short-lived !? :

Or translated into 'street' parlance, we do have problems !!

Oh! well, I am not surprised that we do have differences in what we used to do, and what we can now do :((

With a a small change in our above code,one we would expect to work OK, we get an error - check this :-

=====================================================================================================================

It would appear that we must make the order of the comparisons, match the order in which we make / declare the

table objects, so it has to be 'd then r', and 'r then t' - however in MS the following code works just as well.

Study the following carefully :-

===========================================================================================================

I suppose you could think of the above script as 'sloppy' in how it reads ?! We will just have to live with this situation.

So there you have it, we now know how to code our LINQ queries to include inner joins, and to place the order

of the comparisons 'correctly'.

It does seem a little odd to me that we can't reverse the order, since in doing so we are not doing anything 'clever'.

But there you are, we at least know that we need to take some care ;-0)

Now let us move on to find out more about 'Joining'. Sometimes 'self' joining, as well as 'outer' joining, is very helpful

to the application developer.

See you in the next subsection ....................

PHH - 8th. December 2012.


'Self Join' - using one table twice

'Self Join' - using one table twice

'Self Join' - using one table twice

 Previous topic Next topic

Since I am about to show you an interesting example, from a real life application, we ought to rename

this subsection "Using one table many times over".

Basically, the 'JOIN' is to take rows and concatenate them to make much longer rows.

In most common occurrences JOIN is used to de-normalize our data. However, there are some special

cases where we have other things going on.

I will assume that readers are familiar with joining a customers table with a contacts table, so that we

get rows of customer details including their address etc..

Let us look at a more complex real example - from the 'GroundProbe' project where sensor readings

are taken every 15 minutes by a set of 125 sensors with a data logger device.

Although the raw data comes through with all 125 sensor values in one row of data, this is much more

use to have it split up and stored as short rows, each 'reading' row being for an individual sensor.

If we examine the following image we see that we have five such rows from the 'ReadingNew' table.

Checkout the details and notice the 'Sensor_ID' values :-

===========================================================================================================

Okay then, so we have five values in five separate rows - so what !?

Oh! did I mention "the user" ? He wants all five values to be in a mini table and associated with the Timestamp!

Lets us see the sort of thing the user requires - check this out below :-

=================================================================================

The sensor tags have been changed to ' Temp(n) ' as the sensors numbered 5 through 9 record temperatures.

So lets move on to see how this is done, and to get some LINQ code to do this for us.

First, it will be a good idea to create and test a query statement from within Management Studio.

Here is what I have got working on my platform :-

=========================================================================================================

Yes, it seems a bit weird at first, joining the same table five times over to a 'root' table.

Basically, the above script reads as .... " for any chosen timestamp, add a data value to the growing row as

a new column, with the header specified in the select clause. the condition for the join is based on the chosen

timestamp and the required sensor identity".

Before we go and try our hand at a LINQ equivalent, let us see the lower part of the data output tab in MS.

Notice the number of rows found by our query :-

==============================================================================================================

Let's move on a pace ..............

Moving on to LINQ :

Well, I have just tried to code in C# what we had in our query statement in Management Studio, and

it went remarkably smoothly ;-)

Let us see what the code looks like that I have run and tested, before we discuss certain relevant parts.

Checkout the following :-

===================================================================================================================

The above code differs in as much as the extra 'where' clauses have been inserted in place of the

second part of the ' on ' condition of the joining script.

Secondly, I found it much easier to code the overall query by splitting it into two separate ones - we

have seen this in other subsections.

All we need to do now is try and see what the LINQ system does when making the one 'composite'

query, which it then sends to the SQL Server.

Don't be alarmed with what you see below - remember that this is the side to LINQ which we can ignore

as developers if we so wish.

Check this out below :-

=================================================================================

Just to reassure you, I find it now quite straight forward to code in LINQ as in the image above

this last one, and as long as my tests bring back data that I expect, I just ignore what is being

sent by the LINQ system, to the SQL Server.

Yes, I have to admit, it always seems more complex than my SQL script from Management

Studio, but it does have system generated variable names, which makes reading more difficult.

Also, we need to realise that the LINQ system is always more likely to write a query script

which is much more efficient than what we developers would create and write.

Oh! we had better look at the results of all this effort - see below :-

====================================================================================

At this stage of things it would be useful to study the simple class 'SensorGroup_A' that

is being used - checkout the following details :-

=====================================================================

This should now make most things obvious, or straightforward. Remember, if we have a

developer defined class, to use in place of an anonymous type, then our coding becomes

easier as we try to do more and complex 'things'.

Lets move on to discuss briefly the 'Classic Self Join' ............

Classic 'Self Join' :

Okay then guys, I will come clean, the above example is not strictly a 'self join' as a genuine 'self join'

is when we supply a condition for the same table to be joined to itself. Even though with variations we

can achieve the same result.

Above we used the code as shown below :-

==================================================================================

But in fact, because of how the data exists in the 'ReadingNew' table, we can re-code this so that we do actually

make four genuine 'self joins'.

Lets see how the re-work code looks after it has bee tried and checked out, see the following image :-

====================================================================================

Notice that in code lines 2653 through 2663, the two conditions for each join do actually refer to the

same table - that of 'RNs' and both side of the 'on' clause are 'a' and not one 'x'.

And just in case you think this may not work, here is what the runtime display looks like :-

=======================================================================================

PHH - 10th. December 2012.


'Group by', 'Into' and 'Having'

'Group by', 'Into' and 'Having'

'Group by', 'Into' and 'Having'

 Previous topic Next topic

This first Introductory section on 'Grouping' with LINQ is based on what I have already got working

in my applications.

However, I have just realised when trying to write these eNotes that this topic is much more complicated

and tricky, than I first thought, so we need to have some 'child' subsections for 'Simple', 'Medium' and

'Advanced' grouping.

I hope to learn a lot as I experiment and record my findings for you ;-0)

============================================================================

Okay then guys, let us be brave and tackle 'Group By' which is actually something which is more

advanced even in standard SQL querying.

By this I mean that folks using Management Studio (MS) often do a lot of work before they get to

using 'GROUP BY' and the associated 'HAVING' clauses.

There are some differences in how Grouping is done in LINQ, but it should help us rather than hinder us

once we know what is going on.

To get us going, let us take a small example from the 'Data Logging' application on which I am currently

working.

Here is some T-SQL script in MS which really should have a comparison with '1' and not '0', to find any

'Timestamp' rows which are duplicated. The problem is that my data is too clean, and there are no duplicates

within the 20 thousand 'plus' rows. SO I had to 'fudge' things to get some results to show.

Checkout the standard SQL query script showing in MS - see below :-

============================================================

And as the next image shows we have a total of 20,435 rows :-

====================================================

Also, while we are in MS, I will demonstrate the cleanness of my data ;-0)

Checkout the script when it is set to find any duplicates - see the empty results set :-

==========================================================

Okay then, so much for T-SQL script and the MS environment - or shell.

Let us now move on to using some LINQ technology ...................

Next step - from code using LINQ :

First of all we will use the existing 'script' from the Vulcan.NET version of my application, and send

this in a direct way to the SQL Server.

When I used ADO.NET in my Vulcan development version of the 'Data Logger' app., I had to create

and send the same script which would test and work in the MS 'shell' environment.

We can still do this but by using the 'ExecuteQuery' method on the 'DataContext' class and object.

Check this out below - (and remember the topic will be covered in detail later in this Chapter) :-

========================================================================================================

In the above image we can see the actual T-SQL query which is sent by the LINQ system to the Server.

The next image shows what the returned data looks like when we display it in a data grid - be prepared for some 'odd' output !? :-

=============================================================================================================================================================

The above image is confusing to me, as although the data is correct (shows the date expected etc.) the format

is NOT what I would have expected !?

The next image shows something more like I would have expected previously, when we pass the collection

back as an array of Objects - check this out :-

===============================================================================================================================================================

Please do remember that we have had to change code line 281 from a conditional test for ' 1 ' in order to

get back any results at all. The data is clean and good, and does not have any duplicates at this moment in time.

So for the real application I will change this back to "where p.Count() > 1 " so the correct functionality is returned.

However, as it is for testing purposes, the code seems to do its job - below we count the returned items :-

==================================================================================================================================================

And now we do another test to see what the 14th. item value is (zero based array) :-

=============================================================================================

Now we need to discuss the meaning of line 280 in the above code - it is NOT all it seems to be ..................

'HAVING' - Multiple WHERE clauses ? :

If I put into the query code a 'standard' where clause you will see below that we now have TWO such

where clauses - check them out below, and figure out what the difference may be :-

======================================================================================================================

Yes, for guys coming from a SQL background we would think of the conditional clause now on line 281,

as being a 'HAVING' clause - the clause which applies after the grouping.

Order and position of the WHERE clause(s) :

So let us see if we can do some test to find out more concerning our 'where' clauses.

Fits of all lets see if the position of the first one can be changed at all :-

=========================================================================================

As you can see by the above image of the error box, we can't place it as seen, at line 282.

And now here is another, slightly different, version of the same coding approach - check it out thoroughly :-

============================================================================================================================================

In the above code the first where clause filters out certain rows of data before the 'grouping' takes place.

The second 'where' clause (or HAVING) applies to only 'grouped' rows, and filters those accordingly.

Although we have some success, and get answers similar to those we require, I still think we have a

lot to learn about what is going on 'under the hood'.

Let us move on to consider some issues about performance of our application, and how the code can be

change to improve things a little ...........

CARE - performance and Server querying :

We MUST be careful when writing C# code for LINQ querying, and we have to relate what we write to

how the LINQ system works, and what id does when we use the 'query' variable in later code sections.

Study in detail the following image and in particular lines 284 and 289 :-

============================================================================================================================================

Well then folks, did you spot anything obviously 'poor' about my coding ?

Remember that each time we use 'query' in code after it is defined, this will cause (or trigger) the LINQ

system to send a T-SQL script string to the Server - so here above, we get the SQL Server to do the same

work twice over !! Not good, particularly if there is a lot of data involved.

Before we discus what we need to change, lets view the next two images which prove that the

code actually does work as shown above :-

=====================================================================================

After rearranging the code lines we can cut down the number of times the query is sent for

processing at the Server end of things - check the following and count how many time you see

'query' used after it is defined in line 307.

==================================================================================================================================

If my eyes are working well, and I can still count, it appears as if line 313 is the only place

that we use query, and so the Server itself is only queried once.

We need to take this 'performance' issue into account when we design and write our solutions.

ALSO, we must realise that we still need to get the SQL Server to do most (or all) of the heavy

work of processing the data, and not be tempted to do it in our code simply because it is

easy to do so !

Now lets go and learn in detail what 'Group .. By ...' is all about in LINQ.

See you in the following subsection ............

PHH - 13th. December 2012.


Making a start (SIMPLE)

Making a start (SIMPLE)

 Previous topic Next topic

Making a start (SIMPLE)

 Previous topic Next topic

To help both you and me understand what is really going on with GROUP .. BY ... in the LINQ

coding we see in eBooks and web articles, and SDK from Microsoft, let us start very simple and

gradually work our way up to both full competence and understanding.

Since the documentation in the Help Viewer 2.0 (HV2) (which came with Visual Studio 2012) uses the

MS recommended LINQ query syntax, I will try to use nothing but this information, if at all possible.

Here is the sort of information we see in the HV2 contents :-

================================================================================

The above is nice, I think we can work with this to get us started.

[ .. the problem with a lot of web articles is they are old fashioned, and use both Lambda expressions ]

[ as well as Operator Methods, and Microsoft currently discourage this use .. ]

Okay then, we need to select some suitable data, and try out a typical script I would most probably use

from Management Studio for grouping and getting back aggregate details.

Checkout the following live query I have just made on our existing data :-

=====================================================================

Now let us try some C# code to gradually build up our query, a bit at a time.

To get us in the mood for learning, let us see the results of our first VERY simple query using

the 'ReadingNew' table in the data logging database - check this out :-

==========================================================================================================================

On my system this did take a little while to appear, as there are 2.5 million records, all of which are

in the 'DataGrid' control shown above.

So before we change the code to reduce this number returned, let us study the code which was used

to generate the above results - study this carefully :-

========================================================================================================

In the above image lines 71-73 bring back the 2.5 million items in the collection, as soon as the line

number 75 is run. Remember a 'query' has to be used before the SQL Server is actually queried for returned data.

Now we see in the next image a much faster response when we filter out many of the Sensors, and show

only 29 through 39 of the 124 possible total - check this out below :-

===============================================================================================================

The code line numbered 73, shown below, was added to make this speed-up occur :-

========================================================================

Okay then folks, this is going well, and I have just made a further breakthrough by adding an extra line, and editing

an existing one - checkout this image of some VERY useful results :-

================================

These above return values were created by the following code :-

===============================================================================

It is a combination of the new line numbered 74, as well as some special syntax now included in line 75,

which make this all happen as it does and should !! ;-0))

Finally, in this first 'SIMPLE' section, let us finish by sorting the finalised list of items, and improving the

header text as well - check this :-

====================================

And the code to produce this sorted list large to small in value, is shown below - check it out :-

==============================================================================================

Fine the folk, I am happy with this so far and we have only had to resort to an operator method once.

And since Microsoft did this too in their SDK docs, I am happy enough to do so too.

See you in the next subsection where we will learn even more useful stuff ;-)

PHH - 13th. December 2012.


Going Further - more 'grouping'

Going Further - more 'grouping'

Going Further - more 'grouping'

 Previous topic Next topic

Hi again guys, in our last subsection we got some useful results with grouping data fields

but we only used one field / column value.

In this section I would like to improve our 'grouping' skills so that we can group by multiple columns.

We can then go on in the next subsection to look at what we can do when we JOIN tables and then

wish to GROUP after joining.

First, lets start simple and use our 'Orders' table from last section (in the 'MyCompany' MDF) to get

more than a single aggregate value - here, shown below we get three.

Checkout the following 'Management Studio' details carefully :-

============================================================================================================

With my new found knowledge from the previous section, I have just managed to repeat the above exercise

but in C# code, with LINQ technology.

Here are the results shown in our usual 'DataGrid' - see below :-

===========================================================

Only the formatting of the numeric display seems to be different, and we are not going to

address that issue here, we have enough to do ;-)

Let us now examine what code I have created which does this task as shown above.

Carefully examine and study the following :-

==================================================================================================

Okay, I hear a few shouting about the two lines of ' orderby ', well yes, it looks as though both can be present without

making the compiler complain, but obviously only one will be displayed by the sort order of the final display.

If we remove the first one of these lines, we still get the same sorted list - see below :-

==================================================================================================================================

However, what we can't do is use ' o ' after the 'group .. by' line, as it is not then in scope.

Study the following image and the error message box :-

==================================================================================================================

Well, I did warn you that there were some small differences between SQL script and LINQ code ;-0))

Lets move on and learn some more .......

Grouping by Multiple fields / properties :

In order to experiment with using multiple grouping fields / columns we need to go back to using the data

from the Data Logging application of my son Ben.

Below is some rows of the table entitled "DumpSetHeaderPlusX" - check it out carefully :-

=================================================================================================================================================

In the above image, notice the Year, Month, Day .......... fields / columns.

We are going to group on all of these - in that order- so that effectively we are counting the

table rows for each day - there ought to be 96 rows in the table for each day.

We will use this in a minute or two to see if we have any data missing for any day surveyed,

or looked at.

For the moment lets see the T-SQL script from Management Studio, and the results set too :-

===============================================================================

Okay then, once again I would like to show you an image of success with the C# code I have

just created and tested - check this out, and no particular order has yet been applied, this is

just as the collection data was returned from the Server and LINQ system :-

===================================================

Now here is the full code of the STATIC method used to associate the 'DataContext' property

of the 'DataGrid' control on our WPF form - study thoroughly :-

=========================================================================================================

Okay then, one more step to go, we need to filter out all days with a full 96 count, to expose only those

with missing data - study the following image :-

=======================================================================================================================

Well, I have to say that this is all looking very hopeful (and good), and that I have had no real trouble,

problems or issues while making this subsection 'work' for us.

Finally, checkout how we can sort the output, using an 'orderby' clause which comes after the grouping

and the 'where' clause, which is effectively the 'HAVING' clause of T-SQL - checkout below :-

===================================================================================================================

Enough for now, and one subsection. Let us move on to look at using multiple tables

in a JOIN clause as well as the grouping at the same time.

See you in the next subsection ....................

PHH - 13th. December 2012.


Advanced 'grouping'

Advanced 'grouping'

Advanced 'grouping'

 Previous topic Next topic

Okay then folks, we have made some very good progress with 'grouping' in our LINQ code, but

now in this subsection I would very much like to solve the problem I had yesterday when joining

multiple tables.

Basically the problem is simple enough, I wish to join (or de-normalise) a bunch of Tables, and

then group on column (or field) items from more than one table..

Our first example with look at two tables, Customers and Orders.

In the T-SQL script shown below we have joined the tables on the Primary/Foreign key relationship

of the 'CustomerID' field / value - check this out below, it is Management Studio output :-

=======================================================================================================================================================================

So in the above image some fields are from 'C' and some from 'O'.

We have not as yet done any 'joining' and so this bit is next - try this shown in the following image :-

============================================================================================================

Above we have simply used the date registered for the orders made, to group them into bunches

for each day within one year - yes, a bit silly, but we can only use the data we have to hand ;-)

So we can tell that on the 9th. day of the month (any month) in year 2006, we had 3 orders made.

And although we have not enough of a spread and quantity of data rows, we can make this more complex

as shown in the next image :-

========================================================================================

Notice that we are grouping by field items which come from different (that is separate) tables.

Okay then, our quest is simple enough, how do we code the above query into LINQ query code ?!

Or how do we get a suitable single object to which we can apply our grouping clause?

If we can solve this first double join and 'group', then we should be able to do more complex ones later.

Making a start :

Okay folks, let us write some LINQ query code along the lines of what we have already done previously.

We will use the connection string to the 'My Company' database, and instantiate two in-memory table objects,

as see in the next image :-

====================================================================================================================================

In the above image you see that we have joined (INNER JOIN) the rows of the SQL tables on the Primary/Foreign key

relationship involving 'CustomerID'.

The join bit is easy, it is what we do to provide (using the select clause) table columns in a suitable manner so

use later, that matters.

In the above four lines of the query definition we have provided four fields as output, and named three of these.

Notice that if we print out the query at this stage we get the text or script, and it looks as though nothing as

yet has been either sent to the Server, or returned from it.

Yes, I know, the query text made by the LINQ system is not as reader friendly as what we make ourselves.

That is to be expected.

Running the query :

Once we run the query in the usual fashion, and make an Object Array of the returned results, then it looks

like the following when we bind it to our 'DataGrid' control in the WPF form :-

=============================================================

Okay then, so far we have 'join' and no grouping.

Let us try something a little 'new' to many of us, and re-use the 'query' variable in a second query

expression in our code.

Checkout in particular lines 158 through 161 - study the details below, CAREFULLY :-

============================================================================================================================================

Now the 'IMPORTANT' part of all of this !!!

If we examine in detail the SQL script composed as 'query2' by the LINQ system, we see that it is made

up of both 'query' information as well as 'query2' stuff too.

So by splitting our code to simplify our querying tasks, we have not actually split the final query string which

is sent to the SQL Server.

This is VERY good news as it gives us lots of flexibility for making other sorts of queries, one complex

query into a set of simpler ones.

For now let us see what we get in our data grid when we get back some 'returned' data - see below :-

=====================================

Okay, remember the Server sends back data rows in a totally unpredictable order, unless we specify

the order ourselves.

So here we go - lets experiment with an 'orderby' clause as seen on line 161 :-

============================================================================================================

And the output now looks like that shown in the image below :-

====================================

This is looking good, but we need to experiment with the fields we select for use in our subsequent queries.

Improving our Selection :

Since we are 'object' guys, and should by now be very used to object-member-property notation, and its use,

we can try out a way of selecting which could prove EXTREMELY useful to us in future ;-0)

Let us try to choose all of the fields (or columns) in each of the tables specified in our 'join'.

Then we use use the fields we require in a different way to how we did it previously - time for an image,

and an example bit of code to show you what it is all about - check this out :-

=======================================================================================================

In the above image the code on line 154 is now mush shortened, but in fact is all of the fields in

both tables.

In line 159 we need to extend our method of naming the fields - notice we now have in an extra ' o. ' as

well as having to use the filed/column name and not our own that we previously specified.

However, the rest of the code stays the same, and the results are as follows - they look identical to me :-

=================================

Time to move on to a more complex example, and one which can benefit a LOT from this new technique

we have discovered for ourselves.

Common Advanced "Multi-JOIN" with Grouping :

Okay guys, we did OK with two tables joined, let us now look at a real example which has four joined.

Below you see the Management Studio query and results for a set of relationships of 'Customer', 'Order',

'Order Item', and 'Product'. This is pretty typical of many business oriented applications and databases.

Checkout the details in the T-SQL script below :-

===============================================================================================

So how do we achieve the above with our new way of writing LINQ query code ?

The answer is quite easily, and just copying and adapting what we did earlier - check this out below :-

=========================================================================================================

And for the SQL fanatics amongst you reading these eNotes, here is the query in T-SQL script after the

LINQ system has worked its magic on translating our code (many can just look, and move on ;-0)) ) :-

=============================================================================================

A quick glance at the above shows us that our code saves us a lot of typing and possibilities for errors,

as the shorthand of ours for :-

=============================================

translates into a huge length of text string. Then after that we see the FROM and JOINs.

Out of interest, our data at this point from using 'query' looks as shown in the following image :-

======================================================================================================================

Yes, it doesn't look much use, but that is deceptive indeed !!

Trying to go further :

Okay then folks, let us try our luck a little more before lunch ! Even if we do not get it exactly right

the first time, lets give it a go and code up a 'query 2' for testing.

Study the following in close detail :-

======================================================================================================================================================

As we can see we have a compound query for 'query2' made up from information in both of

our coded 'query' and 'query2' objects.

Let us see what this gives us when run - see below :-

=============================================================================================

Well, not exactly like the MS version but it is really quite close I feel ;-)

Putting things Right :

Okay then you guys, I have had a break, some lunch, and now I am going to straighten things out ;-)

Let us get the Management Studio T-SQL script, and the C# LINQ query code 'in-line'.

Lets make them the same in what they are trying to do, what is grouped and what is selected, as

well as making sure they are in the same requested 'order', as well as printing them out in the

same sort order.

I have two identical lists returned from the SQL server here on my desktop, so lets first examine

the MS version - check below :-

===============================================================================================

In the above image note particularly the order of the items in the 'select' and 'group by' clauses.

And of course the 'order by' clause as well ;-0)

And before we have a final look at the C# code, let us first make a comparison of the above data

output with that shown below which is in our test 'DataGrid' control - check this out :-

==========================================================================================

This looks the same as the earlier output.

Now lets examine the code for query and query2 etc.. :-

============================================================================================================================================

In the above code it was lines numbered 194 through 197 which were edited for content and order.

This seems fine, BUT, a word of warning about 'grouping' generally - take care and make lots of checks.

Very often we do not fully understand the data we are using, even the stuff in front of our eyes. It is all

too common to think something has NOT worked, when in fact it has - it was our misunderstanding, that's all.

We can use theis multiple 'query' approach in other places in this chapter, and indeed eVolume.

The first place that comes to mind is the section on CTE - "Common Table Expressions".

PHH - 14th. December 2012.


CTE - Common Table Expressions

CTE - Common Table Expressions

CTE - Common Table Expressions

 Previous topic Next topic

In the world of SQL querying via Management Studio (MS) and T-SQL, it was the 'done thing' to make the

SELECT statement 'all as one', a single item or entity.

It was also a restriction of the Server too I believe. So in order to allow developers the ability to

select one table of results, and use it immediately in an outer SELECT statement, MS came up

with the CTE - 'Common Table Expression'.

So basically, we created a table using a select statement, and gave it a name for use later.

You can see a simple form of CTE in the following code within MS - see the live results too :-

===============================================================

Please remember that the comparison value of zero will be changed to '1' after testing,

just so that we can use the data I have before me in my live database - otherwise we get nothing!

The following image shows what we get returned as data when we just query with the inner query,

that is the one in the CTE - check this out :-

=========================================================================

Okay then, so where does that leave us now that we are trying to use LINQ code query syntax, everywhere we can ?

Well, for CTE's there is no issue at all, simply because we can code our query in more than one part. "Multiple

queries for the price of one" !!

Because the .NET system holds and maintains any returned data object, we still have this / these to use - which

was not the case with SQL Server querying directly. This is why you got 'lesser' developers making temporary

tables all of the time ;-0)

A better alternative was creating a 'View' object in the database, and calling this like a table - it worked the same.

Personally, I liked CTEs and found them very useful - now we don't have the same needs any more.

In the following live and working example, see how we code the previous CTE in LINQ code, and see the correct

value being displayed as well - note line 279 needs to be changed before proper running of the application, as

I expect one value of each 'Timestamp' in the dump set header file - more than one means duplicates to both me

and the application.

====================================================================================================================================

PHH - 10th. December 2012.


Inner and Outer Joins

Inner and Outer Joins

Inner and Outer Joins

 Previous topic Next topic

My eBooks by Pialorsi and Russo say the following about LINQ and Joins :-

=====================================================================

"By using the 'join' clause, we can define inner joins, group joins, and left outer joins.

An inner join is a join that returns a flat result, mapping the outer data source elements with the

corresponding inner data source.

It skips outer data source elements that lack corresponding inner data source elements. "

=====================================================================

I am not too sure that this is as clear as I would like it to be, BUT, to summarise, an INNER JOIN in

terms of set algebra is one where both sets A and B (being 'joined' ) have no zero (or empty) rows,

that is true for A and B.

However, a Left Outer Join is one where all the rows of set A appear and if there is no match within

set B then an empty sets of rows fields is added.

This can be summarised as :- "all A and some of B, with possibly empty row fields added if no match found".

To guys who have not tried this in SQL it all seems a bit complicated, and they wonder what use it has ;-0)

But you try getting a list of all customers who have NOT placed an order last month and LEFT OUTER JOIN

( LOJ ) is welcome news indeed !!

Here is what the authors say of the LOJ :-

"A left outer join returns a flat result set that includes any outer source element even if it is missing

its corresponding inner source element.

To produce this result, you need to use the 'DefaultIfEmpty' extension method, which returns a default

value in the case of an empty data source value."

With a few well chosen examples I can make this all VERY clear to you, so do NOT panic !

Examples to make this clear :

*** NOTE *** please note that first we will clearly establish what joins are all about, using SQL syntax, before

we move on to see how we can achieve the same using LINQ querying code syntax.

Inner Join :

Let us start with a basic join, sometimes this correctly named 'Inner Join' was/is called just 'JOIN'.

Using SQL querying with MS I always preferred to use the full name of 'INNER JOIN', and I now think

that .NET coders do not look for ways to shave a few characters from a correct name when meaning and clarity

suffers in the process.

Here is an Inner Join, in which every existing row in the Customers data table (A), is joined with each row in

the Orders table (B), as long as it is the same customer - the condition is based on the ID of the customer.

So if we have one customer with an ID of 13 and three orders for this same customer, then the result is a set

of three rows, where the first few fields are identical in all three.

Obviously, the full results set is a combination of these sub-sets for each single customer.

=====================================================================================================================================================================

If we make a small adjustment to our query we can see the subsets grouped together, but I use

the word 'group' in a general sense, as in by order - as seen below :-

[ .. the technical T_SQL clause called GROUP will be dealt with later in this chapter .. ]

======================================================================================================================================================================

So in the image shown above we see that two customers have three orders each, Evette and Drew.

Okay then, lets see what the OUTER stuff is all about ...............

Left Outer Join :

First thing to learn is .... "Do NOT run away from OUTER joins, they are most useful."

Outer joins can easily select for us sets which are quite meaningful - like "those customers not ordering",

and also "Those products not selling." And quite a lot more too, like people not answering a survey etc., etc..

Let us use our current data to find out our customers who have not made any orders, possibly so our sales

team can follow them up with some sort of marketing contacts - check this out :-

=========================================================================================================================================================================

Well, its all very easy to see which customers made no orders, by visual inspection we can say 8, 15, 16 and 17.

So if we add some extra script to our T-SQL script we can place all the null or blank entries at the top of the

results set - check this out below :-

==============================================================================================================================================================

Okay, we can see that LOJ has it uses, but what is the ROJ all about ? .............

Right Outer Join (ROJ) :

This is now easy to understand, as we are told that "A left outer join B" is equivalent to "B right outer join A".

Let me prove this to you with an experiment in Management Studio (MS) - checkout the following :-

=======================================================================================================================================================================

And if we now add a line and a few changes to the query we are left once again with only the customers

who did not make an order - checkout below :-

=====================================================================================

Unfortunately, it looks as though with LINQ technology we do not have the facility to do a RIGHT

outer join, but if that is the case we will have to take comfort in the fact that it is rarely used in queries, AND,

that it can be achieved with a LEFT outer join - and a reversal of the sets being used, A & B to B & A.

Personally, I have used it the odd time, and also think it has its place, since you can add a ROJ to

the end of an already long and multiple set of existing joins. Whereas to reverse things in such a situation

can be a bit of a pain, and may lead to scripting / coding errors. SQL frequent users will know what I mean.

However, we can happily live with this situation if we have to ;-)

Products :

Fine then, before we move on to study in depth the LINQ way of doing this 'joining stuff', let us move to some

different data, that involving product items.

And soon we can find out which product items did not sell in the last month. Typically we would be interested

in 'last month', but with my simple data set we will look at he whole of the Orders table set.

Which items are NOT shifting, or selling ?

The way we go about this is that we use LOJ and select as 'A' the table for which we need all the row items.

So we need to use the Products table. Let us see this data as it stands on its own :-

====================================================================================================================================================

Now as most of us know, in sales and ordering (stock / accounting) systems, the order is usually split into

order lines, with each line of the customer's invoice being one row in the 'OrderItems' table.

Well, we have this situation existing in our database, so first lets look at the last rows of

the 'OrderItems table - checkout below :-

==================================================================

Okay then guys, let us now join the 'OrderItems' table and see what we get - check out this T-SQL script :-

=============================================================================================================================================

Yep! the above image suggests that we have what we are after - BUT - do we have any NULLs we can see / find ?

If we add the extra line to our script, we see that my previous test data does not - check this out below :-

==============================================================================

Okay then, I thought we would have at least one, but then I was taking a chance with data I had not used in months ;-)

We can soon put things to rights, we can add a new product item - then we know it has not been issued as

part of a previous sale !

Below is the data editing screen from MS - study carefully :-

===============================================================================================================

We will now add an extra line to these entries, and the database engine will automatically supply an ID for us :-

==================================================================================================================================================

Once I click outside of the line we are entering, the new data row is sent to the SQL Server and the red/white 'pling' characters disappear :-

==================================================================================================================================================

Okay then, now the big test, what will our 'LOJ' query do for us now - study the details shown below :-

Yep! as we thought, the query script detects unused products.

Now to move on to the LINQ way to do all this ........................

LINQ and JOINs :

Right folks, lets make a start and do the easy bit first, we will use LINQ query code syntax to try out

an 'Inner Join' - that fro Customers and Orders.

INNER JOIN :

Results will be shown in a 'DataGrid' control on a WPF form, as we did for earlier parts of this chapter.

Before we can use tables Customers and Orders we need to have two suitable classes which also map

to the existing tables and their columns.

Checkout the following two classes which do as required :-

================================================================================================================================================================

With the above classes we can now write some LINQ query code which carries out an INNER JOIN and

selects a few of the fields from each table - study these details carefully :-

=================================================================================================================================

And now we have our STATIC method to return an array of objects we can bind it to the 'DataGrid' control on

our WPF form - in this way :-

==========================================================================================================

Once we build, compile and run we see the following output on the form :-

==========================================================================================

The output details shown in the image above are just as we would expect from our new LINQ query code.

Possible Problems / Issues ? :

The only possible problems we may have with this inner joining approach, is that we may need to find a

better, or easier way to select the columns / fields for return.

In SQL we have a few possible shorthand ways of specifying all of the columns, as well as all of the

columns in the first set, plus all of the columns in the second set, and so on.

We do need to experiment and research the documentation.

Here is one thing which works, BUT, is probably not what we require - check this out :-

=========================================================================================================================================

And here is another attempt which may surprise you a little ;-) Check this out carefully :-

========================================================================================================================================

The above appears to give us all the fields / columns from Orders, but the data limited to a successful

join - possibly non-joined Orders data is ignored !? We need further tests and experiments.

However, as you will see in later sections, the easiest way for us in many ways is to define our own class

of object and populate that in our query. I will try to show you, as long as you visit the later sections to

study this yourself in detail later !

Here is our newly defined class :-

======================================================================

And when we make a first attempt to use this new class, and return an Object Array we get

the following output - it is looking good ;-0)

Checkout all the details in the following image :-

=====================================================================================================================================================

Yes, as you can see above it seems to work and also give us all the fields we started up with.

However, it may be nice to now have our STATIC class return a generic List object so here is another working 'success' :-

==========================================================================================================================

The above code, and results, look just fine, so now we need to move on.

Let us look at some 'Outer' joining, and what it may do for us in our projects and solutions ...................

OUTER JOIN :

Okay guys, we are going to repeat the MS work earlier in this section, but now using LINQ querying.

First we need new class definitions for 'Product' and 'OrderItem' - check this out below :-

=======================================================================================================================================================

So now that we have a couple of standard looking classes suitable for LINQ to SQL, we

can now write a static method to get a collection of 'joined' objects - see below :-

================================================================================================================

So far we have just made a standard sort of inner join, and the following results show this - there

are no empty / null values anywhere - check this out :-

============================================================

However, if we make a slight change to the code of line 2334 we can do more. First study this

altered code to see what we will use for the next build and run :-

===============================================================================================================

Let us study the returned data when this code is run, it is quite different, we have three more entries.

[ .. *** NOTE *** I added two more new product items, making a total of THREE !! .. ]

===================================================================================

Notice that the data items for the missing fields have come across (or through) as NULLs.

This means we need to code our query carefully, if we are to just see the products which

have not been ordered at all - check details below :-

==========================================================================================================================================

We also need to view part of the class definition for 'OrderItem' as I had to make a few properties

of type 'Nullable' in order to get this to work ;-)

===========================================================================

So there we have it, our first full and real success with a 'Left Outer Join', not too difficult I feel.

And also remember, if we can do LOJ then we can do ROJ by reversing the order of the input 'sets',

which in our case are tables.

"A 'LOJ' B is equivalent to B 'ROJ' A"

Time to have a break before we move on ..................

See you in the next subsection.

PHH - 12th. December 2012.


Making it clear - 'Flat' JOINs

Making it clear - 'Flat' JOINs

Making it clear - 'Flat' JOINs

 Previous topic Next topic

Having done some extra research work with JOINs in LINQ I realise that we need to make things

quite clear when it comes to what we term a 'Flat' join.

There are times when we wish to have (and need) a 'Flat' join - some may like to call this the standard

SQL 'Inner Join'.

What we need to get VERY clear in our mind is the difference in coded syntax when we use a 'Group' join.

This was NOT obvious to me (coming from a SQL background) and so I will try and save you some heartache

and frustration by showing a couple of examples which should make things very clear on this point / topic.

First the 'Flat' Join :

If we use a common scenario I have come across using SQL script, we can probably make a flat join seem

quite understandable.

Remember, we are not trying to explain LINQ joining coming ONLY from the SQL direction, but when we have

problems to solve in our application code, it may be useful to see what was done to solve these using SQL script.

Below is a common case where we need to de-normalise product field data with order item fields. There is always

going to be a flat one to one join, and no cases of multiple rows of product data for one row of order item data.

This is how the resulting data looks in SQL script, and in the Management Studio 'shell' :-

======================================================================================================================================================

The first two results line (rows) show that Order with and ID of ' 1 ' had two order lines, and

that these were for product identity 1 and 3 - the joined product details show at the end of the row.

Okay then guys, what does this look like when we use LINQ coding ?

Checkout carefully all the details below :-

================================================================================================================

In the above image notice the absence of any 'into' clause, either at the end of line 480, or

on the following line.

A shown this join is an inner join, and we have access to the properties of 'p' in the 'select' clause.

If we had added an 'into' clause this would have made our join a 'Group join' and then we would NOT be

able to access properties of 'p' for our 'Select' clause.

Before we explore and experiment with the above ideas, first let us see the output results :-

==================================================================================================================================================

Yes, I think you agree that this is a nice flat result, and one we required /expected.

Some of you would most likely wish to see what the SQL query script is that the LINQ system composes

from our code, and then sends to the SQL Server - here it is shown below :-

=================================================================================

With a little bit of effort we can improve the column headings by naming the properties in our

'select' clause as shown below :-

===========================================================================

With one more change, for that of the 'ProdTypeID' header, we generate the following output in a

standard WPF 'DataGrid' control - check below :-

==================================================================================================================================================

While we have this code available to us, it is interesting to see just what happens when we

insert a line for an ' into ' clause, the ' p ' properties become unavailable - see below :-

=============================================================================================

The above image shows what we can't do, however, if we do wish to group the properties of the product

rows which match, then we do so by using the following syntax etc. - check this out :-

==============================================================================================================================================

In the above code, lines 484 through 487 are single valued properties, and the one on line 488 is

a collection property - it holds a set (or collection) of property fields, even though our example will

mean that there is always just one in number within the collection.

We need a better example for the next subsection ...............

See you later in .... "a 'Group' join" ..........

PHH - 16th. December 2012.


a 'Group' join

a 'Group' join

a 'Group' join

 Previous topic Next topic

Pialorsi and Russo have this to say :-

A 'group' join defines a join that produces a hierarchical result set, grouping the inner sequence

elements with their corresponding outer sequence elements.

In cases in which an outer sequence element is missing its corresponding inner sequence elements,

the outer element will be joined with an empty array.

A group join does not have a relational counterpart in SQL syntax because of its hierarchical result.

Basically, the way I see it is that we can join tables in such a way that the resulting collection of items,

are objects which themselves may have properties which are collections.

Without, or before, the 'Group Join' all item objects in a collection had properties which were just standard

data types. I think this is what is described as 'flat' !

When we have collections of item object which have properties which are themselves a collection of items,

and we can have "collections within collections", we term this hierarchical I believe. [ Such a data structure

is not directly represented by the standard SQL table model, or 'relational model'. ]

We will do enough tests and experiments to prove this to ourselves, and so we can use the LINQ syntax

in our own querying code.

We are also reminded by Pialorsi et al, that there is no equivalence in T-SQL - I am not sure if it is a good

idea to try and justify this, or say why. Lets just learn that there isn't an equivalence.

So in our example world, the "Customers, Orders, Order Items, and Products" case is hierarchical. However,

we can also invert the tree for this case, and starting with Products, end up with the Orders and then the

Customers which a associated with each product item.

Making a Start :

Okay you guys, let us make a simple, but very effective, start to this new aspect of 'grouping' to SQL folks.

Once again it is good to start with an image of success, so let us study the following output image

shown below :-

==========================================================

Yes, according to our 'DataGrid' display we have four customers who have not made any orders.

It is important at this early stage of using a new 'technique' that we check the actual data in MS,

so here it is shown in the next image :-

As you can see in the above image, we have all the customers from ID 1 through until 7,

but no others.

This means customers 8, 15, 16, and 17 are those with not orders at the current state of our data.

So how did we make the 'DataGrid' bound collection ?

I suggest we study carefully, and in detail, the code I have used to do this - checkout below :-

==============================================================================================================

In the above image we see code which works just fine. We even see a calculated field being made - and

that is the highlighted one called 'Name'.

Remember, the property we have entitled 'Orders' is actually a collection, and as such can't be displayed

in a single cell of the 'DataGrid' control.

This is why we see an empty column of cells under the 'Orders' header. However, since the 'count' of this

collection is a single valued property, it can be displayed.

Let us change our output from this code a little, and sort it using the in-built functionality of the control on

the WPF form.

Notice in the following image each of the customers with zero orders comes at the bottom of the list :-

[ .. the sorted order - by 'NumOrds' property - was done as a function of the header click of the 'DataGrid' .. ]

=====================================================================================================================

Let us now move on to see some of the complexity behind the simple LINQ query code syntax ..........

Hidden Complexity :

You may have noticed how simple, or straightforward the LINQ code was to do such a useful task ;-)

SQL guys may have worried that it was going to be MUCH more difficult, but in reality the complexity

of the SQL query statement has been hidden from our view, as the next image shows - check it out :-

=====================================================================================

For any developer interested in making working applications - or finding solutions to our

business related problems - we can ignore the above once we have seen that it is far more

complex than some of us may have imagined.

Quite simply, it is my opinion that the complexity comes from converting 'flat' data into a

hierarchical object, of collections of hierarchical objects - you know, "collections within

collections".

Lets move on a pace ........

Some extra explanation :

If we use IntelliSense, or the interactive part of the code editor, we can hover over the collection

we have recently created and see what it says it is - checkout below :-

===========================================================================================

Yep! our 'Orders4Customers' is an IEnumerable collection of Order items, and so each of the

properties of the Order class will be saved and 'encapsulated'.

Notice that when we allow the editor to re-format our code, for a number of different reasons in

general use, it prefers to structure our new anonymous type (starting on line 212) as shown

below :-

Before :-

==============================================================================================================================

After :-

==========================================================================

We may have to do some further work on the above to make collections of objects as we so

wish to have them, BUT, to me things look quite usable even as they are.

Lets move on to try some more ambitious 'Group' joining ;-)

PHH - 15th. December 2012.


Something more ambitious

Something more ambitious

Something more ambitious

 Previous topic Next topic

Okay then guys, we need to see a much more complex example of 'Group Join' in action, as it

does not really help us to see only simple ones in the eBooks I have read so far.

From my demo database in SQl Server I have four 'sets' of related data, each in a separate table.

These are the standard examples of Customer, Order, OrderItem and Product.

Before we get drawn into examining small details, let us have an over-view of what is the 'shape' of

our solution 'to be' - check this out below :-

===============================================================================================================

In the above image I have explored coding a solution which uses three separate queries, but where one query

uses a previous query 'result'.

If we get things right we will have nested collections, Items within Orders, and Order within Customers. Products

and Items will form a 'Flat' join.

So let us take the three queries in turn, starting at the 'deepest' one - check below for details :-

==============================================================================

Note that the above join is NOT a group one, just a flat inner join.

And for those who wish to see it the SQL script made by LINQ for querying the Server is

shown below :-

========================================================================

If we now move up the 'nested' structure, or the object tree, we can see the next level and a

'group join', where we group Items within Orders - check this out :-

==========================================================================

This time the code shown above has an 'into' clause and therefore is 'Group' join. So to

match up with that, we have at line 421 a property called 'Items' which is the collection formed

by the 'grouping'.

The those interested the LINQ system creates and sends the SQL query script seen below :-

==========================================================================

Finally, for this example, we need to make a second group join, within our third coded query.

If you like, we can call this the top level, where orders are grouped for customer - see image

shown below :-

=============================================================================

Notice that this query code uses the previous query output (or collection result).

Once again we have a LINQ created SQL script, which this time is less complex that the previous

one, this is now the third :-

=============================================================================

The problem is that when we now try to display the results in a DataGrid control, we only

get the value properties showing in columns, the nested collection data is missing, or not shown.

Here is what I get :-

=========================================================

Okay then guys, if we can't do it the easy way then we will just have to do it the hard way.

Well, when I say 'hard' I actually think it is more fiddly, and prone to us making errors, than anything

particularly complicated, complex, or difficult.

We need to have three 'foreach' loops for our collection, and the two nested property ones.

Take a GOOD and CAREFULL look at the following code, and convince yourself that you know what

it is doing :-

=================================================================================================================================================

In the above code remember that the product detail is now alongside that of the order item, as we

made a 'flat' inner join previously.

Okay then, "so far so good", lets see at least some of what this code produces for us - check this out :-

======================================================================================

We have shown above, the whole of the 'Amy Johnson' section and a line or so of that section

before and afterwards.

If you look carefully you can spot the three orders for her that have two order lines.

Time to move on ........................

Another way to Code the same JOINs - with a difference ! :

Okay then folks, I have to admit it, the next interesting small subsection came about because I thought it

would do something quite different than what it appears to do.

However, the code, and the format of the results, does give us some good material for possible further

development, I feel.

Check out the following image details, particularly lines including 'from' and 'join' :-

========================================================================================

Maybe we can gain some insight into what is going on if we have a quick look at the LINQ created query script

which will be sent to the SQL Server the first time we use the 'query' variable as a 'value' or on the RHS of

an assignment.

Don't be put off by the apparent complexity - just ask yourself if it looks as if any 'Group' JOINs are taking place ?!

===========================================================================

Well, I know what I think ;-0)

To be honest with you, although I consider myself as reasonably comfortable with day to day T-SQL script, the

stuff the LINQ system creates is generally slightly 'strange' to my mind. By this I mean not the stuff I would

use, and not what I have read and seen in books and articles - BUT - there are a lot of various ways to script

things in SQL !!

Let us think some more, particularly when we see what is shown in the 'DataGrdi' control - see below :-

=========================================================================================================================================

Yes, we get 32 lines or rows, within the grid. In fact this is seen in front of the output of the same row

set from a sequence of Inner Joins in Management Studio, giving a 'flat' data return.

Here is the T-SQL code I have wished to shown you since the top of this section ;-)

==========================================================

So what is the rest of the long line of data like which shows in the column entitled 'ourOrders' ?

Well, here is the second part of it, with a reference from the MS lines to the LHS - check this out :-

===========================================================================================================

In the above image we see that we get information about the Order, all of the properties we defined in the "new { }"

section.

And then after these we see the next image details :-

======================================================================================================================================

Finally, we see some details above which relate to the Order Items.

And if you recall we previously noted that lines 1 & 2 come from one order (with ID of 1) while

the lines 3 & 4 come from another order, of identity ' 5 '.

So there you have it - lots to think about an try out - BUT - I have to say that you now have far more

working code to use, copy, and adapt, than the simple and rather limited examples from the eBooks currently

available via the big and well known companies.

So at least be grateful, and don't blame me if it looks complicated - your eyes will adjust to the style, and

how it looks etc., etc..

Take comfort in the fact that we can all do most things required in our applications with what we see in Chapter 13.

Time to move on to another section, see you there ..............

PHH - 16th. December 2012.


First or Default - Single or Collection

First or Default - Single or Collection

First or Default - Single or Collection

 Previous topic Next topic

'Concat' is Union for two sets of same signature

.Distinct

PHH - 10th. December 2012.


'Straight through' commands

'Straight through' commands

'Straight through' commands

 Previous topic Next topic

PHH - 8th. December 2012.


'Straight through' querying !?

'Straight through' querying !?

 Previous topic Next topic

'Straight through' querying !?

 Previous topic Next topic

PHH - 8th. December 2012.


Getting a single value returned

Getting a single value returned

Getting a single value returned

 Previous topic Next topic

page 99 and before .........

first or default !?

last & last or default

single or single or default

element at & element at or default

default if empty

PHH - 11th. December 2012.


Custom objects - returned data

Custom objects - returned data

Custom objects - returned data

 Previous topic Next topic

There is a potential problem with using the simple LINQ examples we see in their hundreds (thousands even)

in the eBooks and the literature, and it all has to do with the 'anonymous' classes which get generated by

the LINQ system - on our behalf.

Most text examples show the LINQ sysntax and then immediately a 'foreach' coding structure which directly

uses the returned type - this works fine, even though most guys are not aware of the object type involved.

The problem comes when we need to write real life code and often STATIC methods which return values.

Usually I write STATIC methods to return lists or single values, and to be able to do this we need a specific

type, or to wrap the returned data into an Object or Object array.

This is a BIG issue for causing lots of problems later on down the line, so to speak. So I suggest we make

a good attempt to tackle this now, so we get things right in the future. Thinking of code maintenance ;-)

Here is some useful information from 'Kolbi' as he is known on the web :-

============================================================================================================

[ CARE - even Mr Kolbi does not always do things the best way - line second to last can be improved !!! ]

So this looks to be VERY useful indeed.

Let us see if we can copy this approach, and make a custom class of our own which will allow us to receive

the data, and from which we can make a generic list which can be passed back from a static method.

As a start, I have used the Sensor Table, and our own Sensor class, on which to base a cut-down class

which I have called 'myTestSensor'.

Checkout the following image, particularly the part which is the non-empty Constructor :-

==============================================================================================

In the above image note the order in which the parameters are placed in line 187 in the constructor.

If we are to use this approach successfully, then we must get the data items in the correct order when

we use the class in our LINQ query code.

Checkout line 2292 from the image following, and see that the 'GPS' related item is first :-

============================================================================================================

We can now use the return from the static method to supply as the associated data for the data binding of

the data grid on our form :-

============================================================================================================

And when the application is run we see the following (if rather uninteresting) data in our grid :-

=============================================================================

Yes, unfortunately, our first working example was not well chosen as far as the data is concerned,

although there is enough to see that it is working - check below the data as seen in the MS shell :-

===========================================================================

Okay then, lets make a few small changes to what we already have, take a look at the following

output in our form data grid :-

============================================

In order to make the above data as it looks, I changed the way I used the custom class instantiation

within the LINQ query code.

Now CAREFULLY check out the following details, particularly line 2293 :-

=================================================================================================

The above image seems to be clear enough, and only works because we have defined our Boolean

property as 'Nullable' and that the 'string' data type accepts 'null' as it comes out of the box.

WARNING - we must make sure that we get the order of the 'Constructor' parameters correct, otherwise

we will switch data values and hence our 'mapping' as such will be WRONG !! So be very careful if you

do things this way.

*** TIP *** :-

For a custom class which is to be used as a return data 'container' class, we may like to think ahead and

provide a whole set of different constructors, which allow for input parameters of 1, 2, 3, .... and so on.

Also we may wish to stick to an organised 'plan' and place these parameters in the same order that they

are declared / defined in the class code itself.

Checkout the next image where I have added and adjusted code lines to fit this new pattern and approach :-

======================================================================================

So if we code using the two input constructor on line 193 we have the following :-

===============================================================================================

And I will leave it up to you to see that the next image shows the correct data output :-

==========================================

Now let us move on a pace .......

List<T> or IList<T> ? :

You may have noticed that Mr Kolbi in his example at the top of this subsection, used 'IList<T>' and yet

I have been using 'List<T>' myself, with great success over the past couple of weeks.

I am not sure what the benefits are of using one over the other, but the SDK documentation does appear

to suggest that there are more members to 'List<T>' and so he may be trying to use something more

lightweight which still does the job OK.

We probably need to find out more on this subject.

Let us move on and learn some more from perhaps a better example ..............

See you in the child subsection which follws this - called "A superior example".

PHH - 8th. December 2012.


a 'Superior' example

a 'Superior' example

a 'Superior' example

 Previous topic Next topic

A Better Example - the "MyCompany" database :

In the parent section to this topic, we saw how to use a custom class object as a 'container' for returned data

from a LINQ query. However, it was not an ideal example as the actual data itself was limited in content.

So to help our understanding, I have moved on to use a more data populated set of Tables, those within

my 'MyCompany' SQL database - the one I use for a lot of 'ClickStart' experimenting.

Shown below is an image with all the Tables listed :-

=================================================

For our 'better' or more 'superior' example, we will be using the Customers table.

Here is a simple query of this table from Management Studio (MS) :-

================================================================================================================

So the first thing we need to add to our C# code is a short static method which returns the correct connection

string for this new database we are using - new as in alternative, rather than new for 'just made'.

===================================================================================================================

Actually, in the above image, all that has changed is the name of the MDF itself, as the file is in the same folder

as our previous one.

Now then, if we have a new table to access, then we need a new class which is fully mapped to that table.

Study the following image, it is similar to those from earlier sections - I just took the Sensor class and adapted it

to suit our needs :-

=======================================================================

Okay then guys, almost done - this LINQ to SQL stuff is very fast for coding up ;-0)

Let us now see what the static method looks like which can access all the data in the Customers table :-

=================================================================================================================

Line 2310 means that for each row in the SQL table a full object of class 'Customer' will be instantiated and added

to the collection which is made up from the returned data.

Remember, a collection is not returned from the SQL Server, it still works in standard T-SQL, it is the LINQ system

which does the conversion for us - under the hood as the US guys say.

Alternative syntax - note the braces :-

=================================

Now then, we wish to call the new static method and try to display the data in a DataGrid control.

Below is the single line of code required :-

================================================================================================

And when we now run our newly updated application we see the following :-

============================================================================================

I will leave it to you to check back with the earlier image of the MS data in a table.

Okay then, now the whole point of this exercise, to make our own smaller custom class, and

we will call it 'CustomerShort' - check it out below :-

==============================================================================

The purpose of making our own class was to use it as a receptacle or container, for return and selected

data items.

Below is shown one way to use the class, but note we have some better syntax to follow afterwards :-

=================================================================================================================

And using this new static method to bind a List<T> to the data grid we need the following :-

===================================================================================================

This now produces a different, and somewhat reduced output in the data grid.

Check out the following :-

====================================================

Well, that all seems easy and very nice - BUT- we do need to take some care ......................

WARNING !!! :

It is VERY easy when using the above coding syntax to mix up our 'mapping' of fields

and properties - table to object - see below for a typical example :-

===============================================================================

Yep! the above does not make much sense I feel.

So what happened, how did we get the mix up ?

Check the next image to see that we wrote the right code but just got it in the wrong place :-

=================================================================================================================

So how do we get around this 'ordinal' or 'positional' style of coding ? To my mind it is a disaster waiting to happen :((

The next small section will help us address the issue ...............

Better ways to preserve data integrity :

What we really need to do is code so that we use class properties rather than parameters in a constructor.

The signature of constructors is not as 'object tight' as using the properties themselves.

Carefully study the following and improved code :-

=================================================================================================================

Lines 2335 - 2337 to my mind are much preferred, and tighter as a coding style.

Here are a few results of this new approach :-

========================================

Also, the benefit of doing things this way is that we do NOT need lots of different 'Constructors', and we

are able to use one class in a number of different ways.

The following code of the next image shows that we can miss out (or leave) a property or two - check this out :-

==============================================================================================================

So we now seem to have a great set of alternatives to using the anonymous type coding, and then having to

fight the passing of such objects, and/or wrapping them as 'Objects' and arrays thereof.

But, when we get this far we think to ourselves, couldn't we have used the full 'Customer' object instead of

having to make new ones ? WE shall see below ......................

However - can't do :

Whatever we wish to do, the following image shows what we apparently can't do, according to the runtime

error message which is displayed - check this out below :-

================================================================================================

So there you have it, a few VERY good strides forward in such a short subsection ;-0)

Lets move on to learn some more new stuff on LINQ.

See you in the next subsection ...........................

PHH - 11th. December 2012.


Custom IEnumerable collections

Custom IEnumerable collections

Custom IEnumerable collections

 Previous topic Next topic

We have previously talked about collections being returned which are of type IEnumerable, or

possibly we should have said that the collections obey the rules of the IEnumerable interface.

If our returned query collection are to implement this interface, then how would we write our own

class to do this ?

Firstly we need to realise that our class will be a collection of objects, and therefore will hold a

group of single custom objects.

Let us be specific when we talk, so let us make a simple object called 'myTestSensor', and then

use this later on to make our own collection.

In the following image we see this newly defined class of object - checkout the details below :-

==============================================================================================

As you can see from the above image the new class has only three properties, when the actual Sensor

table in the SQL database has 12 separate (different) columns.

Because we are just going to restrict the use of this class as a 'receiver' class, we do not need to specify

the attributes as seen in 'Sensor'.

Okay then, so we have our 'singleton' class, now we need to define a custom 'collection' class.

Let us start be naming our new class with a 'suitable' name. How about 'myTestSensorColl' ?

We will keep it VERY simple and 'clean' - with really only the required interface, over and above a collection

property. Study the following details carefully :-

=======================================================================

Okay then guys, our new collection class seems to successfully implement the interface, IEnumerable.

As yet we have not gotten an 'Add' method, but we can use the constructor for the moment, when we start to

do some testing after first checking out the required enumerator.

The following image shows code which I have adapted from the Microsoft SDK documentation. Nothing clever

from me, just the ability to copy and adapt !! Study it carefully ......... :-

===============================================================================

Now then, without wishing to make anything more complicated than it already is, let us carry

out a few tests to see if this does what we wish it to ..........

Testing our new class :

=========================================================================================================================================

=====================================================================================================================

==================================================================================================================

PHH - 9th. December 2012.


IntelliSense in LINQ

IntelliSense in LINQ

IntelliSense in LINQ

 Previous topic Next topic

While learning about LINQ and using the C# code editor, I have found the IntelliSense VERY useful

indeed. It is quite comprehensive and context responsive - BUT - its not 100% I feel.

I suggest you get to use it and let it help you learn ;-0)

Let us take a look at what it offers when we apply the dot operator to a 'query' object - see below :-

=============================================================================

I will now show all of the options I got offered on my editor screen / surface, check these out :-

======================================================================================================================================================

=============================================================================================================================================

Fields in Tables :

The Customer Fields / Columns :

================================================================================

The Product Fields / Columns :

====================================================================================================================================

PHH - 14th. December 2012.


Some general survival advice

Some general survival advice

Some general survival advice

 Previous topic Next topic

set operators ........

sometimes use union intersect and except in place of the select rows query approach

Let clause - page 40 - store to local variable for use elsewhere in query - scope ?

PHH - 10th. December 2012.


Chapter 14 - Set Operators - with LINQ

Chapter 14 - Set Operators - with LINQ

Chapter 14 - Set Operators - with LINQ

 Previous topic Next topic

Please NOTE that these are not part of LINQ, but are Extension Methods (EM).

So classes such as List<T> have a whole bunch of these 'EM's.

Here are a few snips from List<T> :-

=====================================================================

And near the bottom of a long list we see this :-

===================================================================

Not surprisingly, EMs seem to be most applicable to collections.

So if we are to use LINQ a lot then we will need and use EMs as well.

========================================================================

Any guys who have done some T-SQL scripting, and have solved a few different types of real life

problems, may well have come across what is known as the "Set Operators".

- Union

- Intersect

- Except

Set operators are for working in the world of 'Set Algrebra', where we are a level or two above dealing,

or even thinking, in rows and columns. There are a few 'classical' set operators and we will be seeing

three in action here in this section - they are shown listed above.

My personal history of this subject is probably similar to most and many of you - I was aware of them, and

for years got along fine without them - UNTIL - there was a range of specific problems for which 'set algebra'

was perfect for solving, ........ and "oh boy"! was it easy.

I don't yet know to this day, what else I would have done to solve my business problem if it wasn't for the

set operators in SQL Server.

*** NOTE *** These operator are accessed vis 'Extension Methods' which are not part of LINQ but are very

useful along with LINQ query syntax.

'Extension Methods' are part of classes like List<T>.

The operators I am referring to are 'Union', 'Intersect', and 'Except'. These exist in T-SQL for MSSS as

well as now being in C# and useful (and accessible) with the LINQ technology.

'Extension Methods' has a new operator called 'Zip' which is not part of T-SQL and 'MS SQL Server' (MSSS). We will

explore just what this operator can do for us, and what else it bring to out toolbox for solving data problems.

To SQL guys, a 'set' can be thought of as a bunch of data rows. So, customers purchasing last month forms

a set, and customers buying the previous month a second set. Lets call these sets A and B.

Using the set operators with A and B we get a results set which is the answer to different business problems.

We can find out things like which customers bough last month and not this (or vice versa), we can find out

which customers purchased in both months, and the larger set of customers who bought in the two month period.

We will look at these in the particular subsections following this section of the eNotes.

Remember, it is IMPORTANT to know about set algebra, just so you know when it can help you out with

solving your coding problems.

A word about 'signatures' - those of the set items :

Before we get too deeply into the details of the workings of the Set Operators, we MUST get clear in our minds

just what it is that is within the 'sets', and also some idea about their structure etc..

Sets are made up of members, or items. Each member of a set has a signature which makes it similar to the

other members of the set.

When we carry out operations, one set with another, then the sets must contain members of similar 'signature'.

In the simple examples which follow, those involving Customers, we simply have an integer signature. The integer

is the identity of the customer.

Since we are trying to compare customers who have made orders, or not, there is no other data item that is of

interest to us. This will not always be the case, and we could be interested in customers called 'Smith' and the

State / County the abide. In which case the signature would be 'Lastname, State'.

AND, it is also the order in which these signature parameters appear, so 'State, Lastname' is not suitable unless

each set is like this - i.e. has the same data item order. Of course it is also crucial that the data items are the same

data type, as well as that the order is correct, and in SQL cases possibly the field name too.

I find it both important and useful to make careful checks when working with 'set signatures'. Just be careful !!

So look out for signature related details and issues in the subsections to follow.

See you in the next subsection ................

PHH - 17th. December 2012.


Union

Union

Union

 Previous topic Next topic

Okay guys, lets get to work !

First we need to see just what data we have available to us in our test / demo SQL database.

I use SQL tables as this is what I have to hand, but remember the LINQ syntax is similar to all

different data sources, so it will be the same for LINQ to Objects (those in memory and not on disk).

I am using the 'My Company' database - here is the full list of Orders available to our queries :-

===================================================================

Unfortunately, as you can see, we do not have two different months, so we will need to

split the orders group into two - by using the 11th. of the month as a cut-off date.

Below we will use Management Studio to explore the existing data - before we apply LINQ code :-

==============================================================

Notice that in the above image we get duplicated Customer IDs - when I fact what we really require

is just one occurrence for each customer.

We can adjust this using 'distinct' in the T-SQL script - see below :-

=============================================================================================================================

Okay then, the above images show our two groups of customers - one group for the start of the month, and the

other for the days after that.

Now let us use T-SQL to see how the UNION operator works, and also to see that it is 'commutative', meaning that

changing the order has no affect on the result - so A union B is the same as B union A.

Checkout the following details shown in the two images below :-

[ .. one is 'A union B', and the other 'B union A' .. ]

=============================================================================================================================

So the above results show that the final set contains all those unique customer IDs in set A, as well as all

those unique IDs in set B.

Okay folks, let get this to work in code ..........

Moving on to LINQ :

Will will start our simply with our C# code and write a LINQ query to make us a set 'A'.

Here below is the query script created by the LINQ system, and which is sent to the Server :-

=============================================================================================

Let us look at the C# code which causes this to happen.

The following image shows the query code and the data returned from the SQL Server - check it out :-

==================================================================================================================

Okay then guys, we have set 'A', what about making set 'B' ?

Below is shown both the code and the returned data, in a 'DataGrid' control on a WPF form :-

==============================================================================================================

[ Sorry !!! - error on line 526 should be like as follows .. ] :-

==============================================================================

And as you would expect, query for B is not a lot different to that for A ;-)

BUT - what if we complete the task, and code a couple of lines to find the UNION of A and B ?

Checkout the following image details, as well as the final results :-

================================================================================================================

Now if we print out the third query "queryAUB" we ought to see something more complex that what

we got previously - study the next image CAREFULLY !!! :-

=====================================================================================

I like the way LINQ coding allows us to split up out querying task into parts, and then use various

parts, one within another.

Finally on this particular example, see the next image where one form of T-SQL script allows

us to make a 'super' set, which is all the occurrences of items within set A and also all of those

within set B.

Check this out carefully :-

============================================================

As far as I can see this 'Union All' variety is not an option in LINQ.

Lets move on ..............

Customers and Place of Residence :

Before we take a look at another UNION example, but this time with a two parameter signature, we

need to first of all see what our data looks like - the complete set.

Below is the Customers table as it exists in my SQL database as of 'now' - check it out :-

================================================================================================================

And if we just want to make two sets for UK and USA we can do the following :-

==========================================================================================================

But now we need to shorten the signature to just two fields - 'LastName' and 'Country' - check this out :-

===============================================================

Okay then guys, with this two sets of simple string data, let us try the UNION operator - check this out :-

===============================================================

Notice that we get two Taylor entries, one for UK and the other for USA.

This is what we would have expected to happen. However, also notice that one of the 'Smith USA' entries

has gone, because we had a duplicate of that entry.

Likewise, we have the two entries for 'Jones UK' dropping to just one.

Now let us take a chance to look at the signatures ..................

Getting our signatures wrong ! :

In the exploration / experiment shown below, we will see that it is the column / field data

types that matter and not their header / column names.

Let us see what the results of UNION are when we accidentally reverse the column order.

Check out these details :-

================================================================

Yep! as you can see we get a mix-up as far as our data is concerned. But that is only

to the human eye.

If you see the following image, both the columns are defined as ' varchar(50) '.

=================================================

So to the SQL query system (as this script is being run in the SQL Server), there is no different, and so

no rules or conventions have been 'broken' !

Before we move on to examine more details about signature matching, let us see what the resulting set

is when we use the UNION operator on sets of A and B which are only 'Lastname' values.

Study the following image carefully :-

================================================================

Now then more on signatures ............

Mixing Data Types in the Signature :

Let us try out something similar to above, but where we have two different data types for our two columns.

Let us have 'CustomerID' (an integer value) and 'Country' (a string value) - see below :-

====================================================================

So what do we see in the MS panes when we try to reverse the order of the signature

parameters - checkout the following :-

===============================================================================================

It seems as though the error is thrown because 'conversion' is NOT possible.

So I will leave you to try out using UNION with string fields of different length.

Why are we doing so much in Management Studio ? :

Okay, I hear you guys muttering about this being eNotes about LINQ and we are doing a lot

with MS and SQL script directly. Which is a good point.

However, as we saw previously, the LINQ query code does get converted into SQL script when

we are using "LINQ to SQL" and so we do need to have a good appreciation of what is happening

in the SQL Server itself.

Let us now write some LINQ code to try out on our sets A and B when we use both 'Lastname & Contry',

as well as 'CustomerID and Country'.

Here is the code I have written to do what we did previously in MS with T-SQL - study in detail :-

===============================================================================================

Before we look at the full query that was created by LINQ and then sent to the SQL Server, we

need to check the results, or output - see below :-

=======================================

If you check back to the original output from the MS trial, further back up the page, you will see that

this output is identical, both in content and order.

Viewing the queries made by LINQ :

It is instructive for us to keep viewing the queries which the LINQ system composes, or puts together.

So to that end (learning) we will view the three we have in our above code - check these out :-

=========================================================================

There is a little more in the final query text,simply because we named the column output in our C# code.

Here is a reminder of what we did :-

=============================================================================================

Okay folks, lets see what we get when we reverse the fields.

Reversing the 'Signature' parameters :

First we need the correct code to replace identity for 'Lastname' - see below :-

===============================================================================================

This code produces the following output in our 'DataGrid' control on the WPF form :-

==================================

Now then, with our working code in front of us, let us try within the editor to make a change to set 'B' only.

We will keep set 'A' fixed as we try out a few different changes.

See on line 590 below, where I have reversed the order of the items in the return anonymous type, this

change causes the IntelliSense-Compiler interactivity system to throw an error later down the code, in

lines 594 and 596.

Checkout the full details below :-

=================================================================================================

So this is nice, we never get to runtime and so can't cause errors there ;-0)

This of course is not the case when we send our own T-SQL script, as it is then left to the SQL Server to

detect the problem, and throw the error from there, to be sent back to the calling code.

Take time to read some of the error details shown below - I realise that most of the words seem a bit vague

and complicated - BUT - that is how error messages always seem to be, to my mind ;-)

===========================================================================================================

So then, if we can't swap the order of Integer and String fields / columns, what about if we try to

add an extra one - checkout the next two images for full details :-

=================================================================================================================

In the above image we have changed the code to add a third 'string' field called 'City'.

The error messages seem to be the same as before - meaning that we simply have not made a possible

match between the fields in one set and those in the other set. A 'match' being number, type, and order.

Here are the error messages for this second mismatch :-

===========================================================================================================

Time to move on ..............

Applying 'Signature' constraints to 'Intersect' and 'Except' :

Please note that the above comments and subsequent constraints on the signature parameters used,

will apply across all of the set operators, not just to UNION.

So take as much care with signature definition for INTERSECT and EXCEPT as we have been doing for UNION.

Let us go and see how INTERSECT works for us, via LINQ coding, and to solve various problems.

PHH - 17th./18th. December 2012.


Intersect

Intersect

Intersect

 Previous topic Next topic

Pialorsi and Russo say this :-

The Intersect operator yields only the elements that occur in both sequences.

So if we wish to know which customers made orders in both last month sales, and also the

previous month's sales, we use the INTERSECT operator on the two groups of customer IDs.

Doing some Exploration and Experiments :

Once again, we need to be careful as to the data sets we extract and use, from our SQL database.

If we choose an unsuitable set we may well end up with 'nothing at all' as our result !

Let us return to our sets of customers we used right at the start of the UNION subsection.

We have two simple sets of customer IDs which are those customers making orders before and

including the 11th of the month, and another set for those making purchases after the 11th.

I will copy and reuse the C# code, simply changing line 627 to include the operator for INTERSECT in

place of that for UNION.

Study the following image details carefully :-

==============================================================================================

The resulting set of integer values is shown in the following image of the 'DataGrid' in

our WPF form :-

=================================

Yep! this is the correct result, as you can see if you revisit the earlier subsection.

However, it is VERY interesting to see the detailed structure of the query which the

LINQ system created for, and sent to, the SQL Server - checkout the following :-

Notice the T-SQL version of the INTERSECT operator is not used, or included in the query.

This maybe because this approach will also work for "LINQ to Objects" which we will explore

in a short while.

Lets move on ..............

Trying another example with Intersect :

Okay then guys, lets do this part 'back to front' !

Let us start with a simple output data set and work in reverse to see how it originated ;-)

Checkout the results below :-

===========================================

Yes, very simple indeed, in fact just one name, the 'LastName'.

We need to be careful and NOT call this a person, as in fact we start our with names of UK

and USA customers.

What we appear to have done is find the names which are common to both sets - the UK set,

and the USA set.

Let me jog your memory with the next small image - check this out :-

=======================================

As you can see in the above image, Taylor is the only name in both sets.

And what of the final query script which is made by the LINQ system ? Well, we

can see that in the next image :-

Once again we see no inclusion of 'INTERSECT' in this script.

Lets move on to see some "LINQ to Objects" and operator use.

"LINQ to Objects" - with set operators :

Okay then folks, the point about LINQ is that it is one way of coding any collections whether

these collections originate from SQL Tables, or are indeed created in code as .NET collections,

or any other way for that matter.

So now that we know how to use Intersect with SQL we ought to be very easily move on to coding

solutions to our objects we have 'in-memory'.

Fine, this is going to be easy - here is the results of displaying our first set - "Set 'A' " :-

=========================

We now need to see the C# code for the generic List which is being displayed - check this out :-

========================================================================================================

It should interest us that the print out of the query itself seems quite different to those we were seeing from

the example we did concerning SQL tables and data from the SQL Server. We will learn more of this as we

get further into Set Operators with 'LINQ to Objects'.

Here is a final small set as a result to the next code section we will try - not a lot to checkout ! :-

==================================

So we have as our intersection set, Harry and Jane.

So let us take the time to review the full code seen in the following image :-

==============================================================================================

And since this seems easy enough to follow, we had better view the text of the query which LINQ has

created in order to find our result - check this out below :-

=======================================================================================================

Once again, not quite what we would expect to see when we are using 'LINQ to SQL'.

However, if you think you MUST try and shorten this already simple code, be aware that the following code

does work but produces a slightly different result to that we may have expected - study carefully :-

==============================================================================================================

I will now leave you to go back to the UNION subsection and try 'LINQ to Objects' with that operator.

It will be good practise for you ;-0)

Time to move one ....................

See you in the Except operator subsection.

PHH - 18th. December 2012.


Except

Except

Except

 Previous topic Next topic

Pialorsi and Russo say this :-

The Except operator yields all the elements in the first sequence that are not present in the second

sequence.

PHH - 17th. December 2012.


Zip

Zip

Zip

 Previous topic Next topic

Okay folks, this bit should be fun as well as instructive.

'Zip' is a new set operator in that it is included in LINQ but is not found in SQL Server 'T-SQL' script.

It is a bitter like a sideways "join come union". However, I suspect that we may have to be even more

careful that we don't make silly mistakes when using it.

As long as we test and check as we go, we ought to be okay ;-)

In the following image we see a simple code line to do the 'zipping'. Note also the query composed

by the LINQ system - it is "LINQ to Objects" :-

=======================================================================================================

And the result is shown below - this is when we simply pass the result to be bound

to a 'DataGrid' control.

We have seen the issue before, where the items in our collection do not have properties, and so

ONLY those available are output - this is the 'Length' property :-

================================

Just because the collection does not bind properly (or how we would wish) to our WPF control,

does not say that the operation has not worked.

In the next image we see that we can access each item and display it simply in a MessageBox :-

===================================================================================================================================

The above image and code shows that the zipping did take place okay.

So I suppose we ought to look at the simple string collections which worked, but did

not display as we would wish - if we are really honest ;-)

==================================================================

What would be good to do now is try a small but fully defined class of object, and use that for zipping.

Often the very simple samples in eBooks and web articles leave us a long way from being able to cope

with more realistic examples, and I would not wish to be accused to doing the same - since I complain

about it so much myself !!

I think we can use this Zip exploration as a good way to find out more when working with anonymous

types and querying objects.

To help us on our way we need a new class, albeit a simple one - check out the following :-

==================================================================

So in the code above we have a very simple class called, 'NameNumberDate' which

has three properties of different data types.

Let us start out by experimenting with using this class for the input objects to our Zip

conversion code - study these details carefully :-

==============================================================================================

So in the above code we have constructed two generic lists on objects of type 'NameNumberDate'.

We will now try to use these as the two collections to be Zipped together.

Study carefully the next image details :-

===========================================================================================

Yes, as you can tell, we have an output collection which has some data which has been zipped up !!

However, as we found in previous experiments (in other subsections) if we do not have a suitable

collection as returned (output) data, then we get displayed in our bound 'DataGrid' control, only those

properties which are present, and these are system ones.

The result of our binding at the moment is that the 'Length' property is displayed, and nothing else.

Here is our somewhat disappointing result :((

=========================

I think we can do a whole lot better than this .............

Making it work - an big improvement :

Okay then, previously we have focused on the input object types, those in the collections

that we Zipped up.

However, as far as the returned display data is concerned, it is the output collection which needs

our attention, and for us to select and use an appropriate return object class.

Checkout the following results I have on screen at the moment - an improvement I feel :-

===================================================================================

So how did I do that ? (Yes, I know we can improve the data values, but one thing at a time please.)

Below is some code which on line 780 defines the output class (or object type) to be 'NameNumberDate'.

Notice in the following image that we define one property of our class, that of 'ourName' :-

==============================================================================================

The above image shows that we have defined only one property in the returned 'Zip' class.

But before we go any further and do more, lets see the code to print to the 'MessageBox' :-

=================================================================================

Because our output type has changed, we can use IntelliSense to choose the output properties :-

====================================================================

So we can now choose each of the properties to show in the printout, even though we still have

to add some more interesting content as data values :-

====================================================================================================

Okay the guys, let us add some extra lines in the zipping process, and also change some data values too :-

===============================================================================================================================

In the above image remember that the code variables 'itemA' and 'itemB' are actually objects of

type 'NameNumberDate'.

They are no longer string objects as when we started out experimenting.

Now when we bind our results object array to our 'DataGrid' control we get the following display :-

===================================================

Yes, this is more like what we required when we started out with this trial / exploration.

Summary :

So to summarise, we have seen how to Zip up two collections of objects and specify the final, or

returned object type.

Time to move on, see you in the next section or chapter.

PHH - 17th. December 2012.


Chapter 15 - Aggregates - grouping

Chapter 15 - Aggregates - grouping

Chapter 15 - Aggregates - grouping

 Previous topic Next topic

I am writing this section simply because I have had so much trouble myself in getting my head around

the issue of replacing the older SQL script GROUP BY with aggregates like Sum and Average and Count

of the grouped fields.

It probably boils down to me not reading carefully enough the rather large and long-winded error messages

from the compiler / IntelliSense systems.

When you read the following subsection take particular note of places where new anonymous type 'fields'

are supplied with a name - like in line 2624 below :-

====================================================================================================================

In the code shown in the image above, and also in the display image shown below, we are

looking at rainfall values summed and averaged across a single day, and only days with any rainfall

are included in the return set.

Obviously, if we can manage Avg, Sum, Count, then we can do others like Max and Min.

Checkout the following detail of my working app, before we move on to Max/Min :-

==============================================================================

Another issue we may deal with is how to improve the format of the numerical output in the 'Avg' column.

Lets see if we can do both at the same time ;-0)

========================================================================================================================

The third parameter was requested by an error message from the Server it would seem.

Certainly it was a runtime error - see below :-

With this in place as requested, then the code produces the following output when the

returned data is displayed in the 'DataGrid' control - see below :-

It may interest some guys to see the text script of the query composed by the LINQ system.

Checkout the following :-

=======================================================================================

PHH - 19th. December 2012.


a VERY basic 'Grouping'

a VERY basic 'Grouping'

a VERY basic 'Grouping'

 Previous topic Next topic

PHH - 21st. December 2012.


Chapter 16 - the Anonymous Type !?

Chapter 16 - the Anonymous Type !?

 Previous topic Next topic

Chapter 16 - the Anonymous Type !?

 Previous topic Next topic

Ian Griffiths, the author of "Programming C# 5.0" from O'Reilly, has this to say :-

An "anonymous type" was added to the language for LINQ’s benefit:

they enable a query to select specific columns or properties from some source collection,

and also to define custom grouping criteria.

To put it in my layman's terms, it makes some things easy and some others hard ;-)

We need to find out how we can use ATs to make our coding easier, and also how to avoid using

ATs when it will make our lives a misery !!

Because you have not got a name for your type, you can't then use it is some commonly required places.

He goes on to say this :-

====================================================================

The only unusual thing about the generated class is that it’s not possible to refer to the type by

name in C#.

In the debugger, we may find that the compiler has chosen the name <>f__AnonymousType0'2.

This is not a legal identifier in C# because of those angle brackets (<>) at the start.

C# uses names like this whenever it wants to create something that is guaranteed not to collide

with any identifiers you (the developer) might use in your own code, or that it wants to prevent you

from using directly.

This sort of identifier is called, rather magnificently, "an unspeakable name".

Because you cannot write the name of an anonymous type, a method cannot declare

that it returns one, or that it requires one to be passed as an argument (unless you use

an anonymous type as an inferred generic type argument).

Of course, an expression of type object can refer to an instance of an anonymous

type, but only the method that defines the type can use its properties (unless you use

the dynamic type).

So these would seem to be of limited value 'generally'.

==============================================================

I think we can come up with some 'tips and tricks' to make ATs quite usable ;-0)

Lets move on to see some code in action .......................

PHH - 7th. January 2012.


What are these ?

What are these ?

 Previous topic Next topic

What are these ?

 Previous topic Next topic

A good and simple example will start us off on the right foot I feel.

In the following notes (text) I will use AT for 'anonymous type'.

We need to study the following detail thoroughly :-

========================================================================================================================

The compiler does not have prior knowledge of the type in the above code, where we have

instantiated and used three property names 'on the fly' as it were.

Each of the three properties has been given a name by my code, and the type of the properties

is inferred by the value of the code item used.

Once ' x ' is in existence we can use it and its properties like any other type - or so it would appear !?

Here is another useful example :-

======================================================================================

And lets see what we get when we ask the type of the AT to be printed out - check this below :-

=======================================================================================

As you can see we have the 'infamous' <>f_ within the name - this is what is called an 'unspeakable name'.

Now we have seen the above code, and the live results too, we should be able to at least read the next

image to make some sense of the 'select' clause in a LINQ code line.

Check this out below :-

=============================================================================================================================================================

As you will see above, it is line 2290 in which the new instance of an AT is defined.

It is defined with four properties, of type 'DateTime', 'TimeSpan', Double, and fixed String value.

In this example the ' select ' just means that the variable 'query' is a collection of such ATs.

And now we can see the colourful screen output after binding the returned collection to the

'DataGrid' control on the WPF form - check this out :-

========================================================================

Each of the rows is actually one of the anonymous types (ATs) we saw above.

Note the fixed / constant text output from 'myTag' - shown here with column header 'cTag'.

Obviously, the 'DataGrid' column interactive sorts works as per usual. In the above image

I have clicked the mouse to sort the 'Value' column.

Now we have some idea of what anonymous types are, we can move on to other

subsections to see what else we can learn, particularly as far as LINQ is concerned.

See you in the next section ....................

PHH - 7th. January 2012.


How can they be used ?

How can they be used ?

 Previous topic Next topic

How can they be used ?

 Previous topic Next topic

*** a personal comment ***

I see now, looking back, that my introduction to LINQ was made more difficult that it should have

been, simply because I did not find out, and study, enough about anonymous types.

Once we get our heads around ATs, and how to use them, and when NOT to use them, then the

coding of LINQ query code becomes MUCH easier.

Certainly, if we know that we ought to avoid trying to pass ATs 'in and out' of Methods, then that in

itself will be a BIG step forward.

So keep away from returning collections of ATs from a method, and also keep away from supplying

ATs as parameter inputs to ATs and Constructors too.

In the later stages of this chapter we may find out how to do some of this trickier stuff, but for now

we will just 'Keep it Simple'.

First Experiment - same problem, with and without ATs :

Okay then folks, let us look at two ways of coding with LINQ, one using a custom type and the other

using an anonymous type. Its the sample problem with the same data returned and displayed.

Let us look at the custom type approach first.

Below is shown the code for the 'SingleSensor' class I have defined for the "GroundProbe" app.

===============================================================

If we use this 'Type' as the class to receive the returned data we have LINQ code similar to that

shown in the following image :-

===============================================================================================

In the above image, because we are using a defined Type we can therefore return a collection which

is a List of strong types - of 'SingleSensor'.

This then means that we can use the returned data collection in other code as shown below :-

=============================================================================

So what if we use an AT instead ? ...............

Using 'Anonymous Type' in place of the custom type :

Let us now do the same task but this time without my custom type.

Checkout the following LINQ code and compare it with that shown above :-

===========================================================================================================================================

In the above code we see that line 2543 specifies that the objects to be help in the collection which

is returned by the LINQ query, are to be ATs - simply because no 'Type' is specified.

The properties of myDate, myTime, myValue, and myTag will all be of data type determined by the

data which is returned, and the properties of the classes used to create the Tables 'DSHPXs and RNs.

In order to still be able to use the collection of ATs we can use a little trick which entails wrapping up

the AT objects into an 'Object' array - see line 2545 above :-

Now when this array of Objects is returned it can be used as shown below :-

================================================================================

So as you can see, at least we can use the ATs array collection for display purposes

and outside of the method in which the LINQ query was created and used.

Further test on the AT items in the Array :

Okay then folks, we seem to be able to pass ATs as long as we wrap them in an 'Object' cloak.

But what do we see as types of items in the 'Object Array' we pass ?

Let us do a test to find out. Checkout the following image details thoroughly :-

==============================================================================================

As we can see above we still have anonymous types, and the unspeakable name is still there !

However we appear to be able to get to the individual array items okay, but what of their properties ?

Lets try another experiment - check this out below :-

===================================================================================================

The above is NOT what I hoped to see :((

Where are the property names ? And after trying code to force a 'cast' I got no further either.

I am just about at that point where I would say lets take the easy way out and use a custom class.

However, let us see what we can do in the method code - the method in which the AT is created.

Check this out below :-

===================================================================================================

It would appear that we have as much of an issue here as we did outside of the method.

And if we try to access the individual items from the 'query' variable directly, we get another issue, see

the following details :-

===================================================================================================

I think you can now start to see some of the problems and issues we get when trying to use ATs in

our code generally, when in fact we could have defined a custom class.

Here is what we get when we do things right, and use 'SingleSensor' :-

===========================================================================

This time, in the code above, we can access the properties as we would wish.

Although there may be ways to 'get at' properties of ATs I would simply advise to take the clean

and easy way out, and use a custom / business class we define ourselves. This way we don't get

caught out at a later stage.

Demonstration of Accessibility - property values :

If we do use a custom class for our returned collection set, then we can do as seen below.

Checkout the full details shown :-

==========================================================================================================

Ans since we now have a standard type - and not an AT - we can easily get to the values of

the properties of each item in the List - see below :-

===============================================================================================

Before we move on to see more working code and examples in the other subsections of this chapter, let

me make it clear that anonymous types are great to use in some places, and they do make like easy for

the developer guys, like you and me.

And, we can use one AT to define another, and then that one to define yet another.

Where we come unstuck is when we wish the collection items to be persistent enough in RAM that we

wish to access them from other Methods and other WPF forms etc., etc..

If you collection from a query it to be short lived, then ATs are okay.

Lets move on .............

PHH - 13th. January 2012.


a Simple Example

a Simple Example

a Simple Example

 Previous topic Next topic

Let us now take a real example of a LINQ static method I am using in my current application

on "GroundProbe" for my son Ben.

In the following section of code we see that we have one anonymous type of item used to create

a Collection. The collection type is 'DataQuery' according to the 'GetType' as we will see in a moment.

First study the general format or structure of the queries - the first one uses ATs and the second one a

custom class entitled "SingleSensorAvg".

Checkout the following details :-

=======================================================================================================================================

As you can see in the above coded image, the first query is used to define query2.

And query2 outputs a collection of custom objects which we can the pass on in a typed List.

Now let us checkout the first query, that which uses ATs - see below :-

======================================================================================================================================

In the first query we are just joining our tables and choosing the required columns or properties -

depending on whether you are thinking in terms of SQL tables or object collections.

We can now define a second query - that called 'query2' - and handle the grouping we require. Having

'query' defined makes this task easier than it otherwise would be. Chain your queries to make life easier.

However, the second query allows us to pass on a List of 'SingleSensorAvg' items, some of which

can be seen in the display on the WPF form, in the 'DataGrid' control - see below :-

=============================================================================================================================================

By choosing to use a custom class in our second query we end up with a typed List which can be

passed on to any other part of our app, and the property values will be easily accessible.

Another Simple Example :

From the live app "GroundProbe" here is another example of defining a query with an AT for receiving

items, which is then used in a subsequent query which outputs to another AT - so here I am using two

anonymous types.

In order to be able to display the final results I wrap the ATs up in an Object Array.

Once again I find it convenient to do the basic table joining and column/property selecting, before

moving into the task of doing the grouping.

There is a bit of a twist in the tail, as I do something different in lines 3724 to 3734 - we can discuss this

later on - check these details first :-

===================================================================================================================

In the above code line 3726 examines the length of the possible Object collection returned.

If it is to be greater than 15 items in length then the code effectively truncates the array to 15.

There are other ways of doing this, like changing the defined query so that only up to 15 items

are returned from the SQL Server.

We can look at those approaches in detail, later in the eNotes, for now the next image should point

you in the right direction as far as selecting a set number of items is concerned - check this out :-

====================================================================================

Yes, as you can see, line 2411 restricts the 'query3' collection to be 5 in total. So in fact we have three

queries working together in this code section.

The image shows clearly that there are only five rows in the list displayed.

Finally, for this part, lets see what the LINQ system does to compose the SQL script sent to the Server

as a result of our defined queries - see below :-

==================================================================================

Notice at the top of the message box we have 'SELECT TOP (5) ' in the script. To be

expected really !

Lets move on and learn more ..............

PHH - 14th. January 2012.


a Further Example

a Further Example

a Further Example

 Previous topic Next topic

Okay then guys, we are doing quite well.

Let us now look at a case of using an AT (anonymous type) as a way of assembling the columns / properties

of a complex first query definition, so that items from SIX different tables may be then further queried using

a second query definition.

Before we go into further detail I suggest you study the following image in some detail :-

==============================================================================================================

Code line 2690 in the first query definition, allows us to write a much simple second query, where in fact

all we need to do is refer back to ' x, a5, a6, a7, a8, and a9 '.

The following couple of images show how the data items from the AT in the first query, are quite accessible

to our coding when we define the second query - 'query2'.

Below are shown the properties for ' x ' - check out below :-

===================================================================================================

And now the ones in ' a5 ' which will be like the other ' a 's. Check this out :-

==================================================================================================

So after making our coding life easier, we make a final return collection based on the custom

class called 'SensorGroup_A'.

A typed List of these is returned from the Method so it is easier to access the item property data later,

in other parts of our code.

Lets move on ...............

PHH - 14th. January 2012.


Passing data back from Methods

Passing data back from Methods

Passing data back from Methods

 Previous topic Next topic

PHH - 7th. January 2012.


Some tricks and techniques

Some tricks and techniques

Some tricks and techniques

 Previous topic Next topic

PHH - 7th. January 2012.


Chapter 17 - Exporting to CSV / Excel

Chapter 17 - Exporting to CSV / Excel

Chapter 17 - Exporting to CSV / Excel

 Previous topic Next topic

The details shown in this chapter are more a 'support' to LINQ work we may do, than LINQ itself.

Once we have collections of business objects we need to be able to display them - often in a

'DataGrid' control as seen below :-

=================================================================================================

You can see from the above image detail that the WPF form presents two push buttons

which may be used to export the data from the collection of objects, to a file of format CSV or Excel.

There is little real work in the Comma Separated Value (CSV) conversion, but the Excel one needs

some supporting DLL information.

You can also see in the above image that there are some successful export files in the open folder

within 'File Explorer' - the Win8 name for 'Windows Explorer'.

Let us now take a look at part of the contents of each format type.

Checkout carefully the following two images, CSV then Excel formats :-

===========================================================================================================================================

You may like to know that the headings shown in the Excel file version, were created in .NET

code directly, and not by interactive means within Excel itself.

Old and New :

In the past, the old way to export was directly from a DataTable object. This was simply because

the returned data from an SQL query via ADO.NET was in the form of DataTables within a DataSet object.

In a short while we will see the working code for the old way, but for now we need to realise that since

everything in modern .NET coding, and application design, is about business and custom objects, then

we will need to examine the new way of doing the equivalent task.

Since our data is returned to us in a collection of objects, we need to know how to convert a collection

into a CSV or Excel file. This we will also see later, in a subsection or two.

What form our Collection ? :

The final short topic we need to discuss is what form does our collection take, before conversion to

the output file.

We need to take into account that we could have a typed List (that is List<T>), or an array of Objects

which usually comes from an Anonymous type in our collection.

It would seem to me that most guys coming new to this struggle with trying to use anonymous types (AT)

as they would any other type, and to me this is the BIG mistake.

In the LINQ code itself it is relatively easy to use ATs and get back suitable collections, BUT, depending

on what you then wish to do with these collections, you could well be making life more difficult for yourself.

A little bit of effort and forethought before the 'query' is used, can save a LOT of effort and heartache / frustration

after the collection is returned for our use.

What I mean is that if we create a suitable class to receive the query data, and use that in place of the anonymous

type, then we find the subsequent handling and manipulation of our data collection, much easier.

A Personal Remark :

I find it much easier to use 'List<T>' at all times that I can. But to do this I need a defined Type of object.

To get a feel for what I am discussing, study the following image, and in particularly lines 2377 / 78 - see below :-

===================================================================================================================================

In the above image detail we see that results data is placed into objects of type 'SingleSensor'.

This means we can create a type list of SingleSensor objects.

My define class is simple enough, and looks like the following :-

=================================================================

We will see further use of data receiver classes as we go through this chapter.

PHH - 7th. January 2012.


DataTable to CSV file

DataTable to CSV file

DataTable to CSV file

 Previous topic Next topic

=============================================================================================

PHH - 14th. January 2012.


Collection to CSV file

Collection to CSV file

Collection to CSV file

 Previous topic Next topic

==============================================================================================================

PHH - 14th. January 2012.


Collection to Excel file

Collection to Excel file

Collection to Excel file

 Previous topic Next topic

====================================================================================================

=====================================================================================================================

================================================================================================

=====================================================================================================================

===============================================================================================

==============================================================================================

====================================================================================

PHH - 14th. January 2012.


Chapter 18 - Good 'real life' examples

Chapter 18 - Good 'real life' examples

Chapter 18 - Good 'real life' examples

 Previous topic Next topic

=======================================================================

===================================================================================================

==============================================================================

============================================================================

PHH - 29th. March 2013.


Some suitable custom classes

Some suitable custom classes

Some suitable custom classes

 Previous topic Next topic

========================================================

==========================================================================

====================================================

====================================================================

===================================================

.............................................................................................

.............................................................................................

=========================================================================

PHH - 29th. March 2013.


Finding the RAW data

Finding the RAW data

Finding the RAW data

Previous topic Next topic

=========================================================================================================

PHH - 29th. March 2013.


Replacing a large set of values

Replacing a large set of values

Replacing a large set of values

 Previous topic Next topic

================================================================================================================

=====================================================================================================================================================================

===================================================================================================================

PHH - 29th. March 2013.


Extracting sets of column values

Extracting sets of column values

Extracting sets of column values

 Previous topic Next topic

=====================================================================================================================

PHH - 29th. March 2013.


Appendix A - Tips and Tricks

Appendix A - Tips and Tricks

Appendix A - Tips and Tricks

 Previous topic Next topic

NULLs and 'Nullable' - errors on mapping and read collection data.

==========================================================================================================

removing unused 'using' lines for Namespaces

Ctrl +M, + L for collapse

Ctrl + ' - ' to go back in position 'trail' in editor

BEWARE - the anonymous type definition and NOT supplying a name for a property !!!

Can cause a lot of grief.

=============================================================================================================================================

==========================================================================================================

PHH - 14th. August 2012.


Limiting the Collection length

Limiting the Collection length

Limiting the Collection length

 Previous topic Next topic

For List<T> collections use the GetRange(x,y) with possible extension method of ToArray

x is zero based index of starting position, and y is the number of list items.

other things to check - AddRange, RemoveRange, InsertRange.

==================================================================

'System.Array' :

We can limit the first (top?) 'N' items in a returned System.Array by adding a few lines of C# code

to our existing LINQ code static methods.

In T-SQL script we could use the "SELECT TOP 99" type of approach.

However, since we have a collection returned we can process that to limit the display or screen

output. Note however, that this is provided that performance is not compromised.

There is no point in getting half a million items returned from a query, and then throwing away all

but '15' of them ;-0)

So the following approach is for small to medium sized collections - checkout lines highlighted

in particular :-

===================================================================================================================

Yes, in the above image we are using a STATIC method of the 'System.Array' class, which is

entitled 'Array.Copy' - there are overloads for this which add some extra flexibility in its use.

Here are some typical results returned by the code shown above - check this out :-

==============================================================

Yes, I counted a total of '15' rows, representing 15 objects.

Now the Bottom of the collection :

Put quite simply - if we can do 'N' items from the top of a returned collection we can also do

'N' items from the bottom too - how? by reversing the collection and then doing 'Top N', as

this is the same thing.

Getting a bunch from the middle :

We can use an overload of 'Copy' from the 'Array' class.

============================================================================================================================

PHH - 19th. December 2012.


Optimisations

Optimisations

Optimisations

 Previous topic Next topic

I have just come across this web article while doing some work on Metro.

It has some VERY useful points to conside when doing EF and LINQ.

https://rahulgbhatia.wordpress.com/2013/03/12/tips-to-improve-entity-framework-performance/

Thanks to Rahul !

======================================================================================================================

We need to study the above details and take them on-board whenever we can.

Lets move on .....................

PHH - 14th. March 2013.


Appendix B - Entity Framework

Appendix B - Entity Framework

Appendix B - Entity Framework

 Previous topic Next topic

PHH - 11th. August 2012.


Appendix C - SQL Server Connecting!

Appendix C - SQL Server Connecting!

 Previous topic Next topic

Appendix C - SQL Server Connecting!

 Previous topic Next topic

Let us first look at a typical connecting string for SQL Server 2012.

There will be one for the 'full' version and one for the cut-down 'localdb' version.

Here are my details for the 'Full' version :-

=======================================================================================================================================================

And now my working details for the 'Local' version :-

========================================================================================================================================

The only parts you need to find out for yourself are the server name for the full server, and also to know your

folder path and file name for the database file of secondary file name ' .mdf' .

Remember you need to copy the downloaded AW12 database file to a folder where you have complete or full

rights of access.

And you may have to Attach, Detach, and Re-attach this within the Management Studio shell as well, before

you get a working connection with the .NET code.

Just persevere, and don't give up without a good fight !

Hopefully you will know more about access rights and Windows than I do - one of my 'knowledge holes' !

Now then, lets move on to talk about server instances, this is a bit easier, or shall I say more predictable !?

Finding Instances of the Servers on a PC system - using MS :

If there is a version of Management Studio on a PC it may be used to report back the server instances which

are available to you on that PC.

When MS is launched we see a screen similar to that below :-

If the drop list does NOT show you an instance that you think should be present then use the

very last option in the drop list, that of "browse for more".

It may take a while to do the browsing.

I have found that sometimes an instance just installed does not immediately show, then I went to the

browse option - and bingo, it appeared.

Once you have got instances in your drop list the MS 'shell' seems to remember which instance you

were last using, and it keeps the order used for next time you open up.

Finding Instances of the Servers on a PC system - by code :

There is another way of finding server instances, and that is by using .NET code, BUT, be aware that this

method (as good as it is) does not find the new 'localdb' - unfortunately !

Study the following image of the code which provides us with the server instance 'names' - see below' :-

==================================================================================================================================

Lets move on a pace or two .........

Required Namespaces :

In order to use some of the classes shown in the previous code section we need to have certain namespaces present

in the 'using' section at the top of our PRG files.

Check out this image for namespace inclusion as well as checking online 36 :-

=============================================================

If we get a little more information out or our table row objects we see the following details, where only one server

instance is based on version 11 - this is seen at the bottom of the list :-

==========================================================================================================================================

So, as I said earlier, no sign of the 'LocalDB' from this code approach :(

Shame as it was quite useful in the past.

Note that the fourth property displayed is the name of the PC, and this will appear in the connection string as part of the 'source'.

Lets make a Connection :

As we may have seen in other subsections, once we have a correct server instance, and we correctly

know the folder location of our database file, we can code a couple of members as shown below :-

===============================================================================================================================================

The lines 147 and 148 are the connection string, keep all other parts 'as-is' and only change the

Server and the database file-path.

=================================================================================================================================================

Willie says the Connect Timeout set at zero will keep it open indefinitely, or till it is closed another way.

Time to move on.

Lets go and do some LINQ to SQL with these new ideas.

PHH - 16th. August 2012.


Appendix D - Loggig Queries to Server

Appendix D - Loggig Queries to Server

Appendix D - Loggig Queries to Server

 Previous topic Next topic

===========================================================================================================

=========================================================================================================================

=========================================================================================================

========================================================================================================================

Moving the code line down from 100 to 108 we only get one entry in the Output pane

Note the parameters are also displayed :-

=================================================================================================================

=====================================================================================================================================================

=======================================================================================

===================================================================

=============================================================================================================================

http://www.linqpad.net/

============================================================================================================================================================================================

================================================================================================================================================

===============================================================================

===============================================================================

Summary on LINQPad4 :

Well, guys, it was just about 30 minutes ago I first saw the web site, and now I have it running on my Windows 8

platform with VS11 and SQL 2012 ('Denali') too.

All the above images were done with this mix of software products.

The only criticism at the moment is that I seem to have to enter a value for the server instance if I don't wish to

have the last one used.

PHH - 21st. August 2012.


Appendix 'Y' - Putting things right ?

Appendix 'Y' - Putting things right ?

 Previous topic Next topic

Appendix 'Y' - Putting things right ?

 Previous topic Next topic

Paul Nielsen always taught / instructed guys to start reading the SQL 'SELECT' statement from the 'FROM' clause.

I am not sure if he called that a 'logical' reading.

However, in time I got used to ignoring the 'select' clause until I was done with all the rest ;-)

So read below what Julie Lerman says and ask is this just putting things right anyhow ?

=================================================================================================================

============================================================================================================

In the query, c is just an arbitrary variable name that lets you reference the thing you

are working with further on in the query. It’s referred to as a control variable. The

control variable provides another means by which IntelliSense and the compiler are

able to make LINQ more productive for developers.

PHH - 24th. August 2012.


Appendix E - Dependency classes and Notification

Appendix E - Dependency classes and Notification

Appendix E - Dependency classes and Notification

 Previous topic Next topic

PHH - 5th. April 2013.


Appendix X - full XSharp (X#) syntax

ClickStartLINQ

Appendix X - full 'XSharp' syntax

Appendix X - full 'XSharp' syntax

 Previous topic Next topic

Appendix X - full 'XSharp' syntax

 Previous topic Next topic

The Development TEAM for XSharp have used the Roslyn compiler 'facility' to allow X# coders to

use all features that are in the C# we use in Visual Studio.

This then opens the door to xBase guys writing xBase code to tap into the rich facilities that LINQ

provides us with.

I have waited over four long years to be able to share my research and development work with xBase

programmers, and now I can do this through X#.

All of this Appendix section will be in code for X#.

PHH - 19th. October 2016.

================================================================================

>> Query syntax and Method syntax << - we need to know about both.

I sometimes refer to 'Query syntax' as simple syntax.

'Method syntax' uses Extension methods directly.

All will become clear as we study a few simple working examples.

======================================================

Remember that LINQ was created to help us the programmer / coder process 'Collections'.

Look at Chapter 1 to see and read more on 'Collections' as applied to the world of .NET.

Although LINQ can be applied to arrays and lists of simple types - like string, numerical and DateTime, etc.,

LINQ really comes into its own when used with collections of business objects, like Customers, Orders, Products,

and Invoices and the likes.

It allows us to write more declarative code which describes our business solution much more that loops to

tell the computer how to process out data items.

The Good News :

Yes, there is good news for guys coming to LINQ with already established business apps written in X#. We can

add LINQ code to our solution when we make changes and/or add new sections to our existing solutions. It is

not and either / or situation. Simply put, if you have a collection then you can apply to it some LINQ query code,

to create (usually) another collection.

The Better News :

For developer guys using Microsoft SQL Server, we can use LINQ to query the SQL database, once we have made

a connection to it. Making a connection is only a couple of lines of code.

Once we have open our connection we can query the individual SQL tables in a similar manner to using T-SQL code

in queries we send to the database engine.

All our query syntax is made and maintained in the .NET code we create. This means that we have full intellisense

support and also, very importantly, 'compiler checking'. In the past we would only know if our query string sent from

ADO.NET was incorrect when an error was send back from the database engine. This is now changed for the good!

We can stop placing T-SQL code in the database by not using stored procedures and the likes. This is one thing that

many programmers felt uneasy about - for years. This way all the 'stuff' to be maintained is in .NET code.

Below is the C# code to query the Product table and get a result set which is then bound to an WPF 'view' - probably

a DataGrid or ListBox. A lot of "bang for our bucks".

===============================================================================================================

We will see working X# code doing LINQ to SQL in later sub-sections of this appendix.

What with LINQ to Objects and LINQ to SQL, I can't see why guys would use anything other than LINQ, even

before taking up the benefits of LINQ to Entities with Entity Framework 6+ (read as version 6 or later).

Look forward to enjoying the nex few sections of this appendix, its great to learn new and exciting stuff.

PHH - 18th. October 2016.


Removing the need for endless loops !

Removing the need for endless loops !

 Previous topic Next topic

Removing the need for endless loops !

 Previous topic Next topic

As we build layer of abstraction upon layer of abstraction in our coding, the underlying support

systems will do more of the tedious and boring stuff like LOOPs. Foreach, and For/Next etc..

We must not be afraid of more layers of abstraction, they can be GREAT, as well as making our

solution more readable and maintainable.

Let us embrace 'abstraction' !!!

=======================================================================

One aim in creating LINQ and 'Query' syntax was to allow us to process collections without the

need to write loads and loads of FOR loops in our code.

Instead of telling the computer system how to solve our problem we can instead write code lines to

more 'describe' the solution to our problem.

This is called declarative coding, and the idea has been around for decades, and is one main point of 4GLs,

fourth generation languages, to you and me.

I was writing Prolog in the early 1980s to do just this - yes, before Windows, ....... Wow !!!

Here is an nice way to find the total of all the invoices in a collection of Invoice objects :-

============================================================================================

Yes, its all done in one short 'part line' within line 421.

I hate writing FOR loops and I dislike writing FOREACH enumeration loops if I can get away with it.

So you can write your own alternative loop style solution to the above.

I don't care if the nasty stuff is done under the hood for us, the point is we can focus better on our

problem and its solution if we embrace LINQ and also Extension Methods, and even a bit of Lambda

stuff at the same time ;-0)

Free your mind and give the 'new style' a real good go - give up the LOOPS !!!

SQL Server :

In case any of you guys didn't realise it, we can use SQL query statements to do all sorts of things, and guess

what, we never write loops in our statements.

If you are using older fashioned data tables / flat files, which you access using loops (like DBFs) then do yourself a

real favour and change to SQL server, or similar. Use a fully relation database of modern design.

Moving away from DBFs was one of the best things I have ever done.

PHH - 21st. October 2016.


Anonymous Types

Anonymous Types

Anonymous Types

 Previous topic Next topic

Yes, this is the sort of topic title which instils fear into most of us standard and regular guys ;-0((

BUT - don't panic, it will all make sense, AND, we can't do the nice and easy things in LINQ querying without them.

Anonymous types are required for our sanity !

Even if we just use ATs within the body of our querying, before we pass back collections of defined business Type objects.

The way I think of ATs (Anonymous Types) is that they are class 'types' which we can define and use "on the fly". By

"on-the-fly" I mean that we can create then at coding time, without having to design and declare them, AND they have no name.

So they are to mean, or be thought as, a Class without a name.

Here is the content of a message sent to me by Robert when I found that I could not do what I can in C#, and that is just

specify a property data item, and have its name used by default by the compiler.

============================================================================================================================

So the above is good news, this means that in future compiler releases we can use the default style of property name specification.

And all we can do in C# we can do in X# too.

Let us look at some of my working X# code to see an anonymous type being created and used - check the following image details :-

====================================================================================================================================================

In line 262 shown above, we have an unnamed Class with four properties - these are defined as 'lastname', 'BirthDate', 'place' and 'MidName'.

I suggest that you treat case carefully - since we all need to use C# at some time in our coding life, I think at all times we should respect and

preserve the case, as if case sensitivity is everywhere. I have done this now for years, with Vulcan and C#, and it has caused me no extra

problems and issues - try and do the same ;-0)

Here below is another similar use of an AT, except that the new property 'Age' has its value created by the function 'PersonAge'.

Check this out, as well as the function :-

==================================================================================================================================================

The function shown below is NOT perfect, but does the job for testing and demonstration etc. :-

================================================================================================

Now then, moving on a pace or two, lets see some Method syntax and Lambda expression 'stuff' where we are also using an AT we create

'on-the-fly' :-

========================================================================================================================================================

Note that the highlighted section is exactly the same as in the 'simple syntax' shown above on line 268.

Line 305 involves some Lambda syntax for X# which is found under the Lambda sub-section of these Appendix

- 'X' eNotes.

And now below we see a real live example from a test STATIC method I develop much later in these eNotes.

Check it out carefully :-

===========================================================================================

Line 477 is where we start to define our anonymous type. There is no name to the class but it has three

properties, named as 'SuppId', 'ValSum', and 'LineCount'.

For now do not worry about the rest of the query involving a 'Group By' clause.

So whenever we have a 'select' clause we can define an AT to be used for the collection's items / elements.

I find AT's very useful during LINQ syntax and querying, but do find it difficult if they start getting passed around

my code from method to method etc.. So I like to pass out of LINQ methods a collection based on a defined

business class of object.

I show a lot more on this later in the eNotes.

Also we must not forget that intellisense is more likely to be helpul with defined business class types than AT's -

BUT - since I am working without intellisense in VS 2015 at the moment, this aspect needs further investigation.

In the following image we will see the full working method I developed for part of the 'Stock' database for the EF6

sample in later sections.

Note that the first three query produce various AT's - three different ones in fact. On the fourth query I select the

chosen data so that it returns a collection of type List<SuppValCount>, where the SuppValCount class has been

defined by myself.

Study the following carefully :-

=============================================================================================================

If we adopt this sort of approach then the AT's are useful to us - BUT - stay within the STATIC method. Anything

outside of that is then business class objects or collections thereof. Much easier to handle on a non-local (or wider) scope.

Before we move on to another section I would like to say that I find the above approach to querying, VERY effective indeed.

See you in the next sub-section ...........

PHH - 20th. October & 30th. December 2016.


Extension Methods

Extension Methods

Extension Methods

 Previous topic Next topic

??? Please NOTE that these are not part of LINQ, but are Extension Methods (EM). ???

They seem to be part of the LINQ namespace !!!

================================================================

So classes such as List<T> have a whole bunch of these 'EM's.

Here are a few snips from List<T> :-

=====================================================================

And near the bottom of a long list we see this :-

===================================================================

And towards the top of the EMs list we see this below, a very useful EM indeed when it comes to

doing LINQ queries. Check this out :-

=======================================================

Distinct is useful when we only wish unique entries to be in our returned list.

=============================================================================================================================================

Sorry ! - the comment on line 491 may not be fully correct. We are selecting a integer property from 'o'

and so the type should therefore be 'int', a value type.

However, 'Distinct()' does handle the unique part of the solution for us, quite successfully.

Not surprisingly, EMs seem to be most applicable to collections.

So if we are to use LINQ a lot, then we will need and use EMs as well.

========================================================================

Having now done a reasonable amount of work with LINQ and having used a few EMs to achieve results

sets, I will highlight a few of those useful to beginners to LINQ with collections.

=================================================================================================================================

=====================================================

============================================================================================================================

=======================================================================================================

==============================================================

===========================================================================================================================================================

PHH - 30th. December 2016.


LINQ to Objects

LINQ to Objects

LINQ to Objects

 Previous topic Next topic

Okay folks, what exactly is "LINQ to Objects" ?

Well, the answer is easy to supply!

Any collection of objects in memory, and made by us with our code, is considered to be 'LINQ to Object' based.

Think about it like this ... the data does NOT originate in or from a back-end data source, but put together in memory

by our .NET X# code.

Example One (Persons) :

In the following LINQ to Objects example we have a collection of Person items in an "ObservableCollection".

Check out these details before we discuss the details some more :-

===================================================================================================================================================

In the above code, lines 253 and 254 make sure we have on object of type 'ObservableCollection' and some items

within the collection of type 'Person'.

Lines 258 through 262 then query the collection object to produce a results set - BUT - do remember the query in

LINQ technology is only made when the defined/described data set is actually used.

So in our code above it is line 266 which will cause the query to be applied and some results generated.

If line 264 were commented out then it would be line 266 which caused the query to be acted upon.

Let us now see the code for the Person class :-

=====================================================================================================================================================================

Notice that the Person class has one property which is itself a collection, and that is the Name property.

The Name property is actually a collection of objects of the Names class / type.

We can view the Names class in the image shown below :-

============================================================================

Yes, this class is about as simple as they come ;-0)

Please be aware that the classes I shall use throughout the LINQ for X# sections will be as simple as

we can make then - stripped of any extra code for notification of property changes and the likes.

So for samples we may wish to create which need data binding, then we will have to add those code lines

back into our business classes, following the ideas I have posted in my ClickStart eNotes for WPF and

data binding.

Lets now see how to run our test function called 'TenthSample()' - check below for details :-

====================================================================================================

In the above image line 6 may not be necessary for X# which is fully and correctly integrated into the Visual Studio

environment. For now it makes things work.

Okay then guys, what of some output form our simply coded and executed function ?

Check the following :-

================================================================

In order to convince yourself that the resulting output is correct, you need the full test data set - here it is :-

====================================================================================================================================================

And just for the sake of interest as to all of the Console output display we need to see the simple

function I have used in other places to calculate an Age from a date of birth (dob).

Its not perfect but it will do for test purposes later.

Check this thoroughly :-

===============================================================================================

Before we move on we need to examine and discuss the line 262 in which we create an object of the Anonymous

class which is then included in the results set.

Here is the line to be studied :-

===================================================================================================================================================

The 'select' clause specifies which object is to be included in the results collection.

The way we have it coded above the object is of no named class, but it will have a type.

So we supply no name, but do define the property names as well as the data items for each specified property.

In a later compiler (already tested by Robert to work OK) we will be able to miss out (leave out) the name of the property

and the default will be applied, where the name stays the same as that of the data being assigned.

With the current syntax and code of line 262 we will get an anonymous object with properties >> 'lastname', 'BirthDate', 'place', and 'MidName'.

I suggest you consider the case essential, as it would be in C#.

Okay for now, lets move on ...................

===========================================================================================================================================

=====================================================

===========================================================================================================================================================

=====================================================================================================================================================================

===================================================================================================================================================

PHH - 18th. October 2016.


More examples - One

More examples - One

More examples - One

 Previous topic Next topic

For this sub-section we are going to use as our items in the collection, ones of type 'Invoice'.

The Invoice class is defined as a simple business class, seen below :-

=============================================================================================

The hard wired data values and items are seen in the STATIC method shown below :-

=========================================================================================

Note that some invoices have been paid and others not.

So with this data to hand we can now go ahead and create a query with the simple 'query' syntax.

In the following image checkout lines 421 through 425 in particular :-

[ ... notice that we are asking for those invoices which are marked as paid ... ]

==============================================================================================================================

Also note in the above code that we are creating a results collection of items of type Invoice - line 425 specifies that.

In this case we have not used an anonymous class, just kept wit the Invoice class.

Now lets change things so we find those 'unpaid' invoices - check below :-

=============================================================================================================================

Again we used the Invoice class in our results collection set.

Lets us change things such that the results set is a collection of anonymous type.

Study line 425 below in particular :-

======================================================================================================================

*** Whoops ! *** the text label 'made' (above) should have said "value" !

In the above code we have an anonymous type being defined / declared with three properties, 'id', 'val', and 'made'.

Lets change the heading to suit :-

[ .. once again the error of made > value exists .. ]

===================================================================================================================================================

We can now correct things and add to our output - study this below :-

=================================================================================================================================================================

And in one line we can find the total of the unpaid invoices - see below :-

============================================================================================

PHH - 19th. & 21st. October 2016.


More examples - Joining - a start

More examples - Joining - a start

More examples - Joining - a start

 Previous topic Next topic

When we are working with Collections it is similar in many ways to working with Table data in SQL

databases.

There will be times where we have situations in which we need to JOIN two collections on say a

common property.

Later in these eNotes we will see how to join data from two Tables in a SQL database. There we

will join on specified table columns (or fields).

There are a few different sorts of JOINs and we will look at two common types in these X# syntax eNotes.

Once we have the basic skills and syntax in place, we can take JOINing to a more complex level ourselves

if we need to. The important thing is to get some working basic examples.

Lets move on ..........

Inner JOINs - (or Left Inner Join) :

Before we can study the details of an 'INNER JOIN' example, we need to study two simple but usable

class definitions.

If you wish to create your own examples then you will need to define some similar simple classes of your own.

For now, lets be driven by a recent X# Forum post by Robert, and look at a 'Person' class and a 'Pet' class.

Here is the Person class to study :-

[ .. it could have been simpler ! .. ]

=============================================================================================================================

And now the 'Pet' class - this too could have been even simpler :-

Once we have two simple class definitions we then need a small amount of suitable data.

Check the following image for Person data :-

=======================================================================================================================

It is very useful to be able to display so easily what we have in a collection. Well done WPF and data binding !

And now lets check out the Pet data :-

===========================================================================================================

Okay then folks, we have two collections of suitable data.

By now you should have realised that 'Owner' in one collection relates to 'FirstName' in the other.

So these properties are the ones on which we will join.

Here is some working X# code for you to study carefully :-

============================================================================================================

Notice that we can refer, in the 'select' clause, to property values in the primary collection (myPersons) as well

as the joined collection.

The joined collection is in the above example called 'aMyJoin', and it has the same named properties as we

have in the secondary collection of 'myPets'.

So you need to study the details of lines 475 and 476 shown above.

Yes, I know, I could have made the 'select' clause a lot simpler, BUT, we need to do something a bit interesting in

all of this 'stuff'.

Here are a couple of simple alternatives :-

================================================================================================================

In the above image we first have two properties from the primary collection, which is the 'myPersons' collection. Then

we have a couple of properties from the 'myPets' collection.

The order of these 'selected' properties can be changed around by the code order - see below :-

============================================================================================================

The order does not really make any difference to the results data set as such.

Note that we are returning Anonymous Types 'CLASS { .... }' is a way of defining an AT.

We do not need to include all of the properties, only those that we wish to have in the AT.

We can in fact use a property more than once - see below for a simple example :-

=======================================================================================================================================

In the above code notice that the output (results) properties 'First' and 'FName' are actually the same values.

Lets move on ..............

Improving our Inner Join queries :

Lets go and look at another important side to 'Joining' - that involving 'OUTER' joins .............

Outer JOINs - (or Left Outer Join) :

[ .. there are RIGHT OUTER JOINs but they can be coded as LOJs by reversing the collections.. ]

[ .. meaning the primary collection becomes the secondary, and vice versa.. ]

What makes an 'Outer' join what it is ?

Although the sample used below is from LINQ to SQL (L2S) it serves well as an example to discuss the

topic of 'LEFT OUTER JOIN's.

Well first of all let us look at a section of working code ......

========================================================================================================================

Notice in the above image of the results data set, we have a full list on the left hand side - of Customers.

This is the meaning of the term / word 'OUTER' - it means all of the set in the JOIN and the primary collection

has empty / null entries if the outer collection does not have any matches in the secondary collection.

PHH - 21st. November 2016.


More examples - Grouping - a start

More examples - Grouping - a start

More examples - Grouping - a start

 Previous topic Next topic

Okay you guys, lets try to make some progress with 'Grouping'.

Some folks use SQL Server quite a while before they ever get to trying to 'group' data. Others never get there at all.

Grouping can appear difficult or a bit confusing - BUT - it does work and is very helpful in our coding for solving many

different sorts of business objects related problems.

Although grouping comes into its own with more complex business classes in collections, we can at least demonstrate

a few things when using even a simple array of integers.

Below I have taken an earlier sample of code in my test functions and amended it to be a list of integers with some duplicates.

In the following image you will see that we now have three '3's in the list, and four '5's as well.

In the code shown below we are to find out which integers have duplicates, and how many occurrences there are of these duplicates.

Study these details carefully and thoroughly :-

==================================================================================================================================

In the above code it is only the three lines of 373 - 375 which handle the 'grouping'.

First of all we need to view the console output and compare this with the original array data items, to see if

indeed the code has worked for us.

Notice that only the duplicate items 3, 5, and 10 are present in the listed output.

Then count each duplication to see that we have two 10's, as well as four 5's, and three 3's.

So a group called 'g' is made on the original numeric item - since they are grouped by 'num' then all the 3's will be in

one 'g' item and all the 5's in another 'g' item.

Now then, the line 374 makes sense as we are asking to include (filtered) only the 'g's with more than one item entry. And

this is like 'HAVING' in our SQL type of query code we may have used in the past.

Our final select clause specifies an anonymous class with two items, one the numeric value and the other the number of occurrences.

We will need to study a better example, with a more complex collection object, before we can see grouping at its best.

In the next sub-section we will see a better and more illuminating example of grouping. An example which is more likely

to be the sort of thing we create in our business app designs.

See you there .....................

PHH - 20th. October 2016.


More examples - Grouping - going further

More examples - Grouping - going further

More examples - Grouping - going further

 Previous topic Next topic

Before we can do any meaningful work with a more complex example of a collection grouped by a

'query syntax' in X#, we do need to make ourselves a more suitable business class, and also to

make quite a few suitable instances of this class, which we can then access from a STATIC method.

Lets take 'Invoice' as our test example. Checkout the basic code structure shown below :-

==========================================================================================================================

The above code is pretty standard for a simple business class we may construct in our solution code.

And now we need to see the data we provide within the STATIC method. Notice that our return object

from the STATIC method is of type 'ObservableCollection' :-

===========================================================================================

Yes, the above code looks all very standard stuff.

Now we need to see how we can use the hard wired data to try out some X# syntax for writing 'query' code in

LINQ to 'Group' our data in some reasonable fashion.

In the following image checkout lines 392 through 387 in particular :-

===============================================================================================================================================

Yes, it all looks quite understandable, BUT, it will be helpful if we steadily go through the query lines of code and explain what

is going on.

So in line 393 we start out with a collection of Invoice items.

Line 395 shows us that we take each item in the collection, and group it accordingly.

The items can be grouped by one or more key properties, here we have used two, an identity and a date.

This means that each and every item in the new group collection 'g', will have the same ID as well as creation data. The same

customer on the same day.

The 'Where' clause is like a 'HAVING' clause in T-SQL, and allows us to be able to filter out groups where the customer made say

only one order / invoice on a day. As it stands we will see all invoices.

Now then, the final part, what is the format / structure of the item to be included in the results collection?

Line 397 shows that we have four data values (properties) placed into an anonymous class. These are 'CustID', 'InvCount', 'when', and 'Total'.

To access values from the group 'Key' we need to use the syntax like "g:Key:id" when the property accessed is named 'id'.

We have two properties in our 'Key' - we used 'id' and 'when' on line 395 when we defined "on-the-fly" the anonymous class.

You may find this a bit confusing, strange, or daunting, BUT, you will easily get used to it after you write some working code of your own.

Let us see how we can simply see some of our grouped results.

Checkout carefully the following image detail :-

=======================================================================================================================================

Okay then folks, we need to try and generate more useful data and adding this to our results set class returned.

Let us add to each group item some aggregation type 'stuff', like Sum and Average.

Remember that in the grouped results set class, the data items can't be individual ones from the originating collection item. Any

items added must be either 'Key' values or values made in an aggregation process, Max, Min, Sum, as well as the

Average etc. etc..

In the following code I have added some such aggregation items to the returned anonymous class object. Check

out lines 397 through 399 :-

==================================================================================================================================================================

So in the above code we have seven properties included in the returned anonymous class.

I have added some code output lines, and changed the original lines to simplified matters slightly - making

it less confusing.

It seems to me that the above LINQ to Object code is clear enough for you to follow and to copy into your

own examples for testing.

Why not go and do some coding right now ?

Good Luck !

PHH - 20th. October 2016.


Reusing : results sets, group collections etc.

Reusing : results sets, group collections etc.

 Previous topic Next topic

Reusing : results sets, group collections etc.

 Previous topic Next topic

Okay then guys, lets assume that we now can write some LINQ code in either or Method syntax or Query syntax

or indeed both.

So we are beginning to get some skills for returning data sets from either Objects, SQL tables, or Entities.

We need to be careful in our coding that we do not over-use the querying process - meaning that once we invoke it

we should hold and reuse the data returned to us as results.

We may re-query the returned data, we my filter and reduce its size, and we may even just use the top (or first) part

of the data by an effective 'chop' of the collection items.

All of these things need to be carefully looked at and tested out for real.

*** CARE *** - we need to know exactly the Type of item / object that we are dealing with in our collections at all times.

We even need to know the Type of our collection being used - or we can get ourselves into all sort of problems.

AND, we also need to master how to pass our results sets back from a method which generates them, so we can use

the results data for data binding in the calling method, or code. This can get 'just a bit' tricky ;-0)

Lets make a start ...............

'Chopping up' our Results 'Data Set' :

Lets try and copy out of the returned results set 'collection', a smaller number of items.

First of all lets try and place the results set into an array of known Type - here we use 'Object'.

Checkout the following in close detail :-

=======================================================================================================================

=========================================================================

=============================================================================================================

======================================================================================

PHH - 22nd. October 2016.


XSharp Forum - good 'Dictionary' example

XSharp Forum - good 'Dictionary' example

XSharp Forum - good 'Dictionary' example

 Previous topic Next topic

There's nothing like a good example to make things clear to us, and get things straight in

our minds.

Below we will look at such a 'good example' which arose, or came about, from a posting by

Wolfgang in the X# Forum.

Basically, the problem was to start with a filled Dictionary object, and then to identify elements

(or entries) which were no longer needed, and remove them.

There were a few solutions suggested by colleagues, but a few were based on enumerations and

looping.

Here I will display an example of a short original Dictionay - eleven items in total - see below :-

==============================

[ .. eleven elements .. ]

And now we can see a similar (but reduced) list after we have applied a few lines of X# code

at runtime :-

[ .. now down to 8 elements .. ]

Lets look at a bit of my X# code, where we are adding some of the elements, and also the

code for displaying the list in a 'DataGrid' control on a WPF form - see below :-

========================================================

The XAML script for this data grid control is shown in the next image :-

============================================================================================

Yes, that's all it takes to display our data elements, one short line of .NET code and three of XAML script.

Now its time to look at the whole of the code sample, from data being hard wired to the processing code.

Checkout this following image carefully :-

=========================================================================================

Yes, it is only lines 82 through 86 which do the work, and these are actually a re-formatted version

of the single line of code which is shown below :-

========================================================================================================================================================================

When we split up the above single long line to make it easier reading on the eyes etc., we

see that we get the following :-

========================================================================

This query syntax of LINQ is Microsoft's preferred way for us developer guys as we go to a more declarative

way of writing our business solutions.

The idea started in '4GL' (fourth generation language) releases back in the 80's and before, where it was a design

target of the language to represent more the problem being solved, than the way the computer / machine is told

to go about its processing.

I suppose guys like me have been trying to get away from loops of all descriptions, not because of the loops

themselves, but because we were after solution clarity.

In an ideal world we guys should be aiming at a way of solving business problems in descriptive language which

says nothing about how the computer, or more correctly the high level language being used, goes about the

routine sub tasks required to do as we 'describe'.

To my mind the above LINQ code goes quite a step towards this 'aim', or 'target'. It is taking us to being

'describers' and not 'coders'.

I have to confess I got the 'bug' for 4GL and declarative programming in the early 80's with PROLOG. It was

a marvellous experience, and I enjoyed it greatly.

Then Windows came along and we went backwards in many ways for a couple of decades or more ;-0((

Now then 'Nick' if you are reading this, you will understand why I keep away from Lambda expressions

whenever I can. It is simply that the LINQ query syntax uses them 'under-the-hood' but they get in the

way of me using the declarative style to the max.

So please remember that we can use 'L2O' LINQ to Objects on any collection we choose in .NET, it is the

way Microsoft are moving the higher level of 'abstraction' of the coding world of .NET.

Instead of fighting it, we should be embracing it.

After all we no longer miss coding in low level languages, assembler, and all that stuff. Yes, it may be

interesting, and it may be 'fun', - BUT - it does not get us very far with huge interactive business solutions.

Lets move on ................

PHH - 17th. December 2016.

Addendum :

Oh! sorry folks, should have said that the line 86 is a neat way around the general issue / problem with

LINQ of ending up with a collection (of the correct items / elements) - BUT - where the collection is of the

wrong type.

In trying various code samples on my way to the above code I had many collections of the wrong 'Type'.

I solved the issue with a few pearls of wisdom in an XSharp Forum post by Nick Friend - THANKS!

PHH - 18th. December 2016.


Set Operators - with LINQ

Set Operators - with LINQ

Set Operators - with LINQ

 Previous topic Next topic

Please NOTE that these are not part of LINQ, but are 'Extension Method's (EM).

So classes such as List<T> have a whole bunch of these 'EM's. There are literally dozens of EMs

and we need to gradually get to terms with them, and learn how to use them to our coding advantage.

Here are a few snips from List<T> :-

=====================================================================

And near the bottom of a long list we see this :-

===================================================================

As well as this :-

======================================

Not surprisingly, EMs seem to be most applicable to collections.

So if we are to use LINQ a lot (or even a little) then we will need and use EMs as well.

========================================================================

'Set Operations' can be most helpful, and often in a way that can't easily be done in another manner,

or way.

But we do need to realise, right from the start, that the objects which are included in the two different

'sets' of the operation MUST be of the same type.

The operators make 'comparisons' of two sets of equal objects. The results of the operation depend on

that set operator being used.

We have Union, Intersect, and Except. Each doing a good, useful, but different job for us.

With these three, it would seem that we can generate all the other 'results' for overlapping sets.

Here is a useful diagram found on the web :-

PHH - 23rd. December 2016.


Union

Union

Union

 Previous topic Next topic

Okay folks, so what exactly does 'Union' mean to us as coders ?

The following image contains a visual 'description' of what it is.

Basically it is all the elements from one set plus the ones from the second set.

Sometimes in T-SQL for example, we can have an 'All' moderator which means each and every

element in the two sets, and other times without a moderator, we get unique values from both sets.

So that even if a Customer is in both sets this Customer will end up only once in the sets 'joined'

by the 'Union' operator.

Here is an informed picture :-

=======================================

Lets now see how we can use the Extended Method (EM) which does the 'Union' task for us.

Study the following code, and in particular line 405 :-

===================================================================================================================================================================

*** NOTE *** at present (Jan 27th 2017) there is a parser / compiler issue with 'UNION' being a n X# keyword.

Prefixing it with '@@' solves the problem although it is messy. Robert says he will change the status of 'Union' to

allow method use without the '@@' but that will have to wait till the next release.

You may have noticed that the first 'Union' on a code line seems to get process OK, but a second one shows blue and

needs the extra prefix of '@@'.

Lets keep going with what we have, at least it works, if not that pretty ;-0)

Since the results depend on the data entered, and often there are days between parts of the subsection being created,

written about, and screen shots being made, we need to do a live test right now :-

=================================================================================================================================

This is so the code shown and the screen display match up.

We have two customers called Williams and one called Smith. One Williams is named 'Florence'.

And here is the extra DataGrid control which is displaying the results details :-

=====================================================================================================================

Okay then, time to keep moving forward.

Lets now look at a problem with syntax at the moment, but one which may get solved quite soon .............

*** CARE *** syntax for X# :

Lets now do what EMs (Extension Methods) were designed for (to do) - that is 'chain', a bit like functional programming.

We need to use the output from one Union operation, as part input to another Union operation.

Check the details shown below on line 143 :-

====================================================================================================================

To make sure that the current parser and compiler don't get the 'UNION' mixed up with an X# keyword,

we need to add the prefix '@@'.

As you can see above all works very well and we get the correct result.

And below we see some further results which confirm what we would expect :-

================================================================================================================

The above is just fine, however, we do need to see that we can also gain a suitable result by 'nesting' rather than 'chaining'.

Check in particular line 149 shown in the following image :-

=====================================================================================================================

It is interesting to see that the current parser does not complain about this syntax.

Whereas if we try the following code we can't get it to compile - note the line 143 has blue colouration to the

second 'Union' :-

===================================================================================

And if we take this as some type of a lead / pointer, then we can actually get the code to run and get

the correct answer / results, if we prefix the second 'Union' only.

Study the following display at runtime :-

===============================================================================================================================================================

Now lets do a test to see that we are getting uniqueness - that is that duplicate elements are excluded

from the operation.

We can take the above sample and tweak the data somewhat - lets give it a go ............

==============================================================================================================================================================

*** GOOD NEWS ***

Last evening (Jan 30th. 2017) version 2.9 Beta of the X# compiler was released by Robert and his team.

After updating my existing RC version of Visual Studio 2017 to the very latest :-

===============================================

this new version played nicely with the 2.9 compiler and the VS integration done by Fabrice.

It now shows the changes the Team has made as far as parsing and compiling the 'Union' extended

method (EM), as you can see in the next image shown below :-

========================================================================================================================================================

Check in the code above on line 179 where I have removed the '@@' prefix to 'Union'.

We get no blue colouration and no error messages, it just works as we may expect, or certainly like to see.

Lets move on .....................

PHH - 23rd. December 2016 & 27th. & 31st. January 2017.


Intersect

Intersect

Intersect

 Previous topic Next topic

What we need is a good example to help is understand the set operator 'Intersect'.

Lets say we have a STATIC method to find customers ordering last month and one to find

another group of customers ordering this month.

If we then need to know which customers order tow months running (in both months) then we

can easily just use the set algebra 'operator' called "INTERSECT".

So we only get a list of those customers in the parts of the two sets which 'overlap'.

If we had details for three months then we could do two intersections and find those customers

ordering in all three successive months.

In the past, I have found this approach VERY useful to solve business problems which otherwise

I would not know how to even approach getting a solution.

======================================

PHH - 23rd. December 2016.


Except

Except

Except

 Previous topic Next topic

=======================================================================================================================================================================

PHH - 23rd. December 2016.


Zip

Zip

Zip

 Previous topic Next topic

============================================

=======================================

PHH - 23rd. December 2016.


Comparing sets - IEqualityComparer, etc..

Comparing sets - IEqualityComparer, etc..

 Previous topic Next topic

Comparing sets - IEqualityComparer, etc..

 Previous topic Next topic

Okay then guys, what exactly does 'equal' mean, when we compare one 'thing' with another.

A is equal to B is an easy idea to have in mind if the things A and B are simple enough.

If A and B are integers than this is dead easy 13 equals 13 and 26 does not equal 39 !

When our objects to compare get complex, then we need to specify which properties of the

objects are to be compared, and in some cases 'how'.

Once we have created a clear and 'tight' definition of what equals is to be, then we can use

that comparer class to do our business object comparison for us.

Here is a simple example from a web search, although it is in C# we should be able to use it

quite nicely in our X# samples and test code. Check it out :-

Oh! - we need to see this class first :-

=======================================================

So that the following code section now makes more sense :-

==============================================================================================================

Okay then guys, I think we need to do some X# coding to try this out for ourselves.

Then when we have it working for Union we can move on to a more complex, or appropriate, example.

Possibly something related to our Stock database.

Here goes, fingers crossed .............................

Fine - things now working okay, we have an operational X# example with a couple of my own bits too.

================================================

===================================================================================================

=================================================================================================================================

===========================================================================================================================

===========================================================================================

==========================================================================================================================

====================================================================================================

PHH - 30th. December 2016.


Variables in the 'query' body

Variables in the 'query' body

Variables in the 'query' body

 Previous topic Next topic

https://www.dotnetperls.com/linq

=====================================================================

Let us do some testing samples / examples with 'let' - here is a start :-

============================================================================================================

==============================================================================================================

=============================================================================================================

==========================================================================================================================

=====================================================================

=============================================================================================================================

=================================================================================================

=============================================================================================================

*** CARE *** some of this coding may not work with L2S (LINQ to SQL) and L2E (Entity LINQ).

The code needs to be able to be transposed into a standard T-SQL scripted query.

We can try some of this stuff later in the L2S and L2E sub-sections.

PHH - 30th. January 2017.


EM's - some common usage

EM's - some common usage

EM's - some common usage

 Previous topic Next topic

** Remember ** that when in this section we talk of 'EM's we are talking about Extension Methods which are in

the LINQ namespace.

If you prefer, 'LINQ EMs', as a name or title.

===============================================================================

In order to examine some of the uses of the existing Extension Methods (EM's) we need first to choose to

try out some of the very commonly used ones.

In this sub-section we will not use the sugary syntax of the Microsoft query syntax, but the pure application

of the methods - more or less in the way that we applied Functional Programming.

Remember that because we are using L2O (LINQ to Objects) then our collections are all in-memory ones.

So that means that generally the collections will be of type List<T> or ObservableCollection <T>.

They can be others but modern coding probably uses those mentioned above in preference to the older classes

of array / collection in the .NET framework.

Modern code also focuses on generic types, so we commonly now use 'List<string>' or 'List,Customer>'. The

type either being a system one or our own business class.

Lets see some of this stuff in use in my working code .................

OrderBy & OrderByDescending :

These are very common and we will need to use then correctly in many, many places in our LINQ code.

===============================================================================================

Remember too that the Lambda 'variable' can be anything of our choosing. I have chosen 'item' but equally

it could have been 'element' or, as is more likely in other peoples code, 'p' for Product.

Here is the code to use the static method to fill some GUI display control :-

========================================================================================================

And here is what it looks like at runtime :-

===================================================

Notice above that it is the ProductCode items that are in order A through Z. So digits come before 'a' or 'A'

Lets move on ...............

OrderBy >> ThenBy & ThenByDescending :

Okay guys, we are now going back in time to the earlier 80's and the time of Tandy computers.

They had a software data 'program' (not an app as the name was not then used / invented) which allowed

the user to do what was termed 'a multi-key sort'.

Meaning that we could specify a number of sort columns (fields) - to have a sort in a sort.

An example of this may be to sort on Lastname and then on Firstname, for a bunch of customers.

This is achieved in LINQ with the use of the 'ThenBy.....' EMs - check below :-

=========================================================================================================================================

And this code produces the following GUI output at runtime :-

==================================================================================

Obviously the Ascending /Descending order is independent - one key to another.

So we could have Lastname in ascending order and then Firstname in descending order, if

we chose to do so.

It usually makes sense to do the sort last, or before the 'ToList'. However, it would appear that it

is unlike the SQL equivalent and often (always?) the sort order is preserved from one EM to the next.

Personally, I would not risk it, and I will apply my sorts last, as I have become accustomed to in

my use of T-SQL for SQL Server.

Lets move on .............

Where :

The 'where' clause as it is known in T-SQL script is the place at which we filter our results set.

We can have one or more such clauses, and sometimes it is easier to read, as well as get logically correct,

if we place our filter restrictions in more than one 'Where' statement.

Here is a working example of what I mean :-

========================================================================================================

Here below is how we call the method in order to do a test :-

======================================================================================================================

And yes, this could be done in one statement as seen below :-

======================================================================================================

Because 'Where' usually involves logic and logical operators, and even compound logic, it is always a good idea

to test thoroughly. I would say thorough testing is a MUST !!!

Where can be placed in virtually any position in the sequence of EMs and if used after a GroupBy it can act as

'HAVING' in a standard SQL statement.

Try things out for yourself, try to push the boundaries of what you are doing and trying. Get some experience,

and in that way gain yourself some confidence.

Select :

{ .. 'SelectMany' is dealt with in the next sub-section .. }

This EM has extra complications (or complexity) in its use, depending on which properties (or columns) we

wish to choose to be selected.

Then we have extra complexity to do with using either a defined business class or an 'off the cuff' AT -

remember AT stands for 'Anonymous Type'.

We will go through these options one at a time to see what the syntax looks like.

Okay then folks, this 'Selection' topic ranges from simple to use and understand, to much more of a complex

topic if we look at the advanced form of applying Select and SelectMany.

Actually, it not the select part in itself which adds a lot of complication, but more of what we actually select

and into which object class type we wish the selected properties to be gathered.

The best way to approach this is to start simple, and look at working samples which get progressively more

complex as we change what we wish to 'select'.

Here is a very simple, but common type of example :-

===================================================================================================

Reading the above LINQ code we can say that we are taking the collection of OrderLine objects and sorting

them by the OrderIr property, then placing each of the collection objects (as they are) into a List of type

'OrdeLine'.

Note that the collection item has not therefore changed. This is about as simple as we can use the 'Select'

extension method.

Moving on, and going forward ..................

Lets now select only some of the properties of the objects within a specified collection.

In the next image shown below, we can see lines 342 and 343 which via the Selection EM pass back to the

new collection an object of undetermined name (anonymous) with properties defined and assigned within the

curly braces - quantity, price, order identity and value - check this out carefully :-

========================================================================================================

We will deal with line 340 in the next sub-section when we discuss the use of 'SelectMany' to flatten entity structures.

Line 344 was simply added (along with line 341) to reduce the huge number of returned items within the results set.

Left unfiltered we got GUI displays where all lines looked virtually identical to the more than casual glance.

Well the guys, what happens if instead of going more complex, we actually go much more simple. How does

this affect what can be passed back by 'Select' ?

And now to another way of 'Selecting' ..... use of a specially defined business class.

Checkout this code below - lines 730 through 732 :-

=======================================================================================

On line 730 we are instantiating a new object of type 'SuppValCount' as well as assigning the

values to the properties of the new object.

As you will see below, the three properties Count, Value, and SupplierId, have been defined in the

class definition - see below :-

=======================================================================

Is can prove to be a useful alternative to using anonymous types. One definite, or obvious, benefit is

that we know exactly the type of collection that we are passing back as the results set - more correctly

we know the exact type of the items in the collection.

So line 734 reads that we are returning a strongly typed List of 'SuppValCount' items.

Let take a few more paces forward .......

Distinct : [ .. we need to be careful ! - what makes one item distinct from another ? .. ]

Okay folks, now an easy to understand EM which still has quite an impact on our coding and business solutions.

Quite often we need to know a list of item values (for a particular property) but only have each item appearing only

once in the results list.

The following example is very typical - we want a list of Cities covered by our Customers sample - check this out :-

========================================================================================================================

Yes, it means that we have no customer from London, or Edinburgh for that matter.

Obviously we very often have 'Distinct' at the end of our chain of EMs but we don't have to.

Looking at the output list, we also seem to have had our list placed in order A-Z !

I am not sure we can always rely on that without forcing it with our own OrderBy clause, or EM.

Lets move on ..........

Distinct<T > :- with more complex object items in the collection :

{ .. see the next sub-section for Distinct<T>() .. }

for now ... here is a picture of success :-

=================================================================================================================================================================================

See later (next subsection) when is one Customer equal to another Customer ?

Lets move on ........

Single & SingleOrDefault :

DefaultIfEmpty :

First & FirstOrDefault :

Last & LastOrDefault :

PHH - February 25th. 2016.


EM's - some more advanced ones

EM's - some more advanced ones

EM's - some more advanced ones

 Previous topic Next topic

In this short sub-section we will see how in just a short amount of code we can achieve a lot.

In fact the example shown below can be written in one line of code, if we so choose.

The EM's which make this example a more advanced one are the two methods 'SelectMany' and

'GroupBy'.

===========================================================================================================

SelectMany :

Yes, the 'SelectMany' extension method is extremely useful to us coder guys.

We can deal with the Entity situation where we have a collection within a collection within another collection, and

so on down the 'data class tree'.

Soon below we will see how data can be 'flattened' for Customers where each Customer has a property

of an Order collection, and each of these Orders has a property which is a collection of OrderLine entities.

The above is quite a usual business solution situation, so we need to know how to cope and deal with it.

It (SelectMany) allows us to easily 'flatten' an Entity data structure. I will explain this more clearly below.

First lets see how a working example does a useful job for me in my working test code :-

======================================================================================================

I have and Order entity (defined class) which has one property which is a list of 'OrderLine' items, and the length

of this List can vary - possibly between 0 and 9 in most cases.

The property oLineList is a list of 'OrderLine' objects.

After the application of the EM entitled 'SelectMany' we have a collection of items which are a combination of

the properties of the Order class, followed by properties (and their values) from the OrderLine class.

Yes, this does mean that the first of these (the Order properties) are duplicated for each of the items within

the short list of OrderLine items.

BUT - we only see these data fields if we choose to place then in the select specification.

Here is a display of the above selection :-

==========================

The new flattened structure is bit like when we in T-SQL script JOINed two tables. That sort of idea!

Of cause we can flatten from more than one level of depth, we will do three levels further down this subsection.

First lets see below for another two level example, with values from both levels (of collections) :-

And an even Better Example - first two levels flattened ! :

[ .. Customers is our 'top' level collection .. ]

===================================================================================================================

Above and below, we have a Customer class property value, as well as in the same row or line, an Order property value.

If we can access both classes, then we can choose just what we wish. Check below :-

==========================

Now, then two values will not normally be sufficient, lets try a few more - see below and study carefully :-

================================================================================================================

To action this static method we only need do as follows :-

==========================================================================================================

And here is the GUI display at runtime :-

===========================================================================

Okay, good so far, now what about going a level deeper ? ..................

And now three levels flattened ! :

Remind ourselves, Customers, Orders, and then OrderLines - three levels of collection.

Below is a LINQ query statement with two flattening 'SelectMany' clauses within it :-

==========================================================================================================================================

As we can see above, the second SelectMany operates on the data output from the first one, which is then filtered

before being processed by the second SelectMany extension method.

Examine the following data display at my GUI test surface - work out for yourself which collection

originally held the data field (property value).

[ .. Sorry ! - the output had to be split into two halves because of WPF window restrictions in my code / script .. ]

==========================================================================================================================================

I think we can agree, that we have data values from each of the three collection 'levels'.

Lets now have some fun and look at what first appears to be a strange 'Flattening' of our Entity data.

Flattening - a special example to work out what's happening :

In doing my testing and experimenting, research if you will, I came across the following syntax example.

Yes, it was my own doing, as I did not really know what I was doing at the time ;-0)

Line 741 and 742 are the ones to focus on in particular :-

================================================================================================================

And here is the GUI display from the LINQ query :-

===================================================================

So what is it that we are actually seeing ?

Well, first of all we need to realise that we have three 'select' statements / clauses.

The last one in line 745 just selects all the current properties - AND - as such it may not even be needed

at all. Just because the 'select' normally comes last in the order of the applied EMs does not say that

it has to do so.

Lets see if we can do without it :-

===================================================================================================================

Yes, this works just fine, no need at all to have a 'select' clause or EM at or near the end of the 'chain'.

Join :

Okay guys, you probably think that if we are using EF6 then we don't need to know how to use the 'Join' facility.

To some degree this may well be true - BUT - we still do need to know how it works and how to apply it.

So lets try to get some useful results.

To JOIN two collections we need a common property on the elements within the two collections.

Our collections for this test are of Orders and OrderLines - both my business classes.

The common field / property is 'OrderId' and integer property.

Here is the X# syntax that I have gotten to work :-

=========================================================================================================================================

And here is the GUI output display :-

================

The calling code syntax is as follows :-

========================================================================================================

===========================================================================================================================================

Distinct<T>(.. comparer class object ..) :- with more complex object items in the collection :

=================================================================================================

===================================================================================================

GroupJoin :

Repeat :

Yes guys, something else in the EMs list that I am not really sure about !?

But before I have a moan and complain, lets see the X# syntax to make 'Repeat' work for us - check this out :-

=====================================================================================================

If would appear that all it does is add three groups of selection into a long list and then we can finish off

the selection process in the normal way, making suitably typed Lists etc..

Please let me know if you think this has any profound uses ;-0)

PHH - February 25th. 2016.


EM's - Contains, Any, All and Zip

EM's - Contains, Any, All and Zip

EM's - Contains, Any, All and Zip

 Previous topic Next topic

Contains :

There are a few ways 'Contains' may be applied / used.

*** Note *** also there is more than one 'Contains' method - they are not all the same !

Below is the one belonging to the String methods, and one we are all most likely to have previous met :-

==============================================

And here is the entry in the web Help :-

=========================================================================================================================================================

Lets first look at this one, it is as shown below - when we are examining a Property value - this is not the LINQ EM as we have

already seen above.

Another 'Contains' method is seen when we are looking at items in a collection - this is the LINQ extension method.

First lets look at the 'smaller' ('lesser' ?) of the two cases stated :-

==========================================================================================================

In the X# code shown above we are wishing to include collection items (type Customer) which have a

'Firstname' property value containing the word (or character string) of "Williams". This is a 'String' type method.

Here is the GUI results display produced :-

======================================================================

And now below is the calling code used :-

===========================================================================================

Before we look at how to use 'Contains' with a collection of items, here is the information in the web Help eNotes :-

[ .. for the 'System.Linq' namespace .. ]

=====================================================================================================================================================================

As you can see above (second entry), we can use a Comparer class to specifically define what it is we are

considering (and testing) when we call two items 'equal' or not.

It is the Comparer class which defines what 'equals' means to us. And this idea of 'equals' can be very varied indeed.

And 'YES', we can have more than one Comparer class for the same item collection - it all depends

on us and our business problems. Logic, situations, etc., etc..

Here is one class of Customer comparer - its simply based on first and last names :-

[ .. a reasonably sensible idea .. ]

===================================================================================================

[ .. note that there are two methods required by the Interface definition .. ]

The above code would be improved, and made more realistic, if we also included the Post Code.

This would then mean that we are less likely to confuse similarly named individuals.

The same Comparer classes are used with 'Distinct()' - and a couple more extension methods as well.

The Comparer(s) pair with (or match) the business classes - and are just used by suitably defined extension methods.

Lets move forward, and see if we can use 'Contains' with a suitable Comparer object.

Checkout the following, and notice that we are using 'CustomerNameComparer' :-

==========================================================================================================================

In the above test we are using a retrieved object which is a single Customer object of identity equal to 3. So we already

know that the object is in the customers list, if indeed we have a full list of stored customers. So 'True' is not surprising.

Now then, let's make a new customer, and one which is not in the list already. I will add my daughter :-

====================================================================================================================

This time, the code on lines 389 through 394 does not see the new customer object in the full

list of stored Customers. Which is what we should expect to happen.

And for comparisons sake, here below is the stored Customers list :-

============================================================================================

As you will see, no Laura Hepburn, so the runtime message box display of 'False', two images above,

is actually correct.

However, we can continue this experiment by first adding to our long list the new object formed with

my daughter's details - check this out below :-

==================================================================================================================

Okay then, this also makes good sense, so now the Customer object made from Laura's details is seen as

being contained within the collection.

Lets move on a pace or two .............

When I first defined my business class of Customer I did not include a 'PostCode' property, and so

I can't now try out a Comparer using it to tighten up the comparison.

You can do that for your homework task ;-0)

Lets move on ......................

All :

=====================================================================================================================================================================

================================================================================================================

========================================================================================================================

Any :

=====================================================================================================================================================================

=======================================================================================================================

========================================================================================================================

Empty :

=====================================================================================================================================================================

AsEnumerable :

========================================================================================================

Zip :

Its not as confusing as it first looks.

IEnumerable :

Useful as it is a STATIC method ...........

======================================================================================================================================================

IQueryable interface :

Non-static ..........

=============================================================================================================================================

Lets try out some simple test examples.

Here is my X# interpretation of a simple sample from the Microsoft MSDN eNotes :-

===============================================================================================================

And changing some variable text names may help further :-

=======================================================================================================================================

And since we are less likely to do the task shown above, here below is a more likely requirement :-

====================================================================================================================================================

Yes, at the end of this "action task" we will have a list of objects of a new class, specified by the anonymous

type defined by our code on line 422.

Remember " class { .. , .. } " is the basic syntax outline for an anonymous type definition / declaration.

As of this moment in time, I am not sure how useful this Zip method will prove to be - BUT - at least we

have an example of working syntax in X#.

Lets now check that we do have objects with properties - study the following :-

========================================================================================================================================

Looks just fine to my eyes .....

See you in the next sub-section.

PHH - 30th. January 2017 & 3rd March 2017.


EM's - Min, Max, Sum, Average ...

EM's - Min, Max, Sum, Average ...

 Previous topic Next topic

EM's - Min, Max, Sum, Average ...

 Previous topic Next topic

Average :

==================================================================================================

Average "Order value" - 'Stock' system :

The following two images speak for themselves :-

[ .. yes, I know, we could have printed the value to only two decimal places .. but hey! ? .. ]

=============================================================================================================

==================================================================================================================

======================================================================================================================================================================

======================================================================================================================================================================

Count :

============================================================================================

Whoops ! - ignore comment line 137 >>

====================================================================================

Max :

====================================================================================

Whoops! - ignore comment line 121 ......... >>

====================================================================================

==============================================================================================================

================================================================================================================

Min :

Smallest Order value ............................

=====================================================================================

Sum :

=====================================================================================

===========================================================================

Sorry ! - ignore comment line 145 below ....... >>

==================================================================================================================

============================================================================

PHH - 26th. February 2016.


LINQ to SQL

LINQ to SQL

LINQ to SQL

 Previous topic Next topic

https://www.codeproject.com/articles/215712/linq-to-sql-basic-concepts-and-features

Above is a very useful article - detail and background in C#.

========================================================================

Remember that although we are discussing 'LINQ to SQL' ('L2S') we are actually addressing the issue of seeing

and using the X# syntax required to apply LINQ to retrieving data from a SQL database.

The whole topic of 'L2S' is quite an extensive one and can't be covered in any sort of complete manner in these

conference eNotes.

Once you have enough knowledge of the X# code syntax then you can explore 'L2S' more fully for yourself.

However, remember that 'LINQ to Entities" with EF 6 or 7 (Entity Framework) may well be a better option for

you, particularly if you are starting a project from the beginning, scratch as we say.

Microsoft would appear to have created the 'L2S' technology as it was on its way to later creating 'L2E' - so

for many of use LINQ to Entities with Entity Framework 6 / 7 is currently a far better option.

However, L2S is simpler to get going with, and get practise with LINQ syntax, which is the real purpose of

these eNotes.

=================================================================================================

http://www.codeproject.com/Articles/215712/LINQ-to-SQL-Basic-Concepts-and-Features

Before we get into studying my samples, and the code I have written and tested, lets look at some useful

information and statements found in the above web link.

Do not be afraid of 'ORM' it is our friend ;-0)

===========================================================================================

===========================================================================================

Okay you guys, first the good news - "there isn't any bad news" !

Once we can manage to create and write code for 'LINQ to Objects' then we have all the skills

required to apply to SQL, and 'Entities'.

All we need to do before applying our LINQ query (and other) skills, is to make a suitable connection

to our database, and find out how to use the connection to get back collections of data objects from

the Sever, or SQL database engine.

This is the part where we need some 'ORM' skills to define our own business classes to map with existing

SQL tables in databases we may wish to use.

The whole bunch of stuff related to LINQ, like anonymous types, Lambda Expressions, Method syntax,

simple 'Query' syntax etc., etc. is all the same. Simple !

We just need to be a bit careful with our 'mapping' - some little things wrong means we may see no data

items in our returned 'results set'.

We may have to be a little more careful about the types of the results collections we have returned after

the query and how we then pass them through Methods to be 'Data Bound' in WPF forms. But the LINQ

stuff is all pretty much the same - Objects, SQL and Entities.

This is why I suggest you do a lot of work with LINQ to Objects, and STATIC data methods, before you go

further, and try accessing back-end data with a MS SQL Server (MSSS).

Get good first, and do lots of tests and trials with code written against "LINQ to Objects".

=============================================================================

*** CARE *** the hardest part of starting to code with "LINQ to SQL" is getting the right code and syntax to

make a connection to a chosen and suitable database, with an appropriate Server on our PCs / systems.

Although it is simple in concept - making a connection, in reality it is ALWAYS tricky for me - I have to work

at it, before I get success. But it is doable ;-0)

And once your head is into it then it even becomes easy ! Believe me, it the same for me as it is you.

Lets make a start - we need to have the correct Namespaces and Assemblies present in our code header as

well as in the References section of our solution.

*** Note *** Have a look at the sub-section from here, called "Find your Servers - SQL" so you can the find

any Servers on your own system.

I have split up the tasks required into smaller sub-sections so as to not complicate things too much.

Work through the following subsections one at a time in order.

Good Luck !

PHH - 18th. and 21st. October & 3rd. November 2016.

Addendum : (from MSDN)

========================================================================================================

November 8th. 2016.


Understanding : what we have not got in VS, as yet

Understanding : what we have not got in VS, as yet

Understanding : what we have not got in VS, as yet

 Previous topic Next topic

If you search the web you can find articles which suggest easy ways to help you make a 'L2S' project.

However, they are based on C# and therefore there are currently many more Templates available to the

user and coder, than in X# as I write these eNotes.

This is not really a problem it just means we need to understand more fully what we are trying to do and achieve.

Which is never a bad thing anyway ;-0)

The old article (2011) in "CodeProject" shows this following image :-

=================================================================================================================

However, I realise that this looks to be an old version of Visual Studio, as also most likely Windows.

Here is what I get for an Added Item in a C# project in VS 2015 :-

===================================================================================================================================

Notice that we still get an option for a template named "LINQ to SQL Classes".

Well fear not, we will manage without it and do things manually - ourselves.

So roll up your sleeves and get ready for some learning.

Maybe in time we will see a Data folder for Template options as we see above for C#.

Possible Work Around - if you must ! :

Of cause you could experiment by creating a C# project and adding the item shown above for 'L2S'.

Once you have the Classes for 'L2S' then they can be converted into X# syntax.

This exercise may be a very good one for learning. Maybe I will give it a go later !?

PHH - 7th. November 2016.


Compare 'L2S' with 'LINQ to Objects'

Compare 'L2S' with 'LINQ to Objects'

Compare 'L2S' with 'LINQ to Objects'

 Previous topic Next topic

http://www.codeproject.com/Articles/215712/LINQ-to-SQL-Basic-Concepts-and-Features

Read the following carefully, to get your mind 'right' before you start :-

===============================================================================================================================

Lets now move on ....................

A Simple Comparison of queries for Objects and for L2S :

Let us do a simple couple of tests with code in our project editor.

First the 'Object' flavour of a query - check below :-

=============================================================================================================

Well folks, I don't know what you expect to see when we print out the 'ToString()' value for our Object query, so here

below is what we get - don't panic about it looking long and/or complicated - we need it to compare with what we get soon (below).

=========================================================================================================================================================================================

Lets leave the long line printed above, and see what we get in comparison from a L2S query.

Lets start with a VERY simple one - check below :-

========================================================================================

Oh! - that is different !!!

We seem to get a proper SQL statement - the sort we may write ourselves when dealing with SQL and even ADO.NET.

Here below is a more complex L2S query printed out for us to read :-

=======================================================================================

You will notice that the two 'OrderBy' clauses have been changed so that the query is in-line with the way

T-SQL is used for SQL querying - the OrderBy clause is last.

So we can assume that the compiler 'under-the-hood' does some interesting and even amazing things to

create 100% correct SQL query statements from the code which is written in a way close to 'Method Syntax'.

Once you start to write more complex and complicated queries you will see just how amazing the work

'under-the-hood' actually is.

PHH - 6th. & 7th. November 2016.


Find your Servers - SQL

Find your Servers - SQL

Find your Servers - SQL

 Previous topic Next topic

Now then guys, before we can create and use a suitable 'connection string' for our own PC systems, we

need to know what our Server(s) is or are called.

We need at least one server, so that we can use it to open an existing MDF - the secondary file name for

all data files we may use.

We can worry about the MDFs later - where they are on our system and access to folders etc..

Lets now look at the working C# code I have in my old eNotes on ClickStart :-

http://www.winclickstartvulcan2.net/WebNotes/ClickStartLINQ/ClickStartLINQ.html

Note below that I seem to have had three instances of a MSSS :-

========================================================================================================================================

Now then folks, all we need to know is how to change the syntax to the X# flavour of the .NET code.

I have one problem however, my PC set-up has changed a lot over the years and I now no longer have the 'Denali' and earlier

version of MSSS installed.

Lets see just what I have and how the X# code looks - check below :-

=================================================================================================

Above is one named instance and here is the instance 'count' :-

======================================

If you wish to have another way to see what is installed on your PC then trying the 'Programs and Features' from

the Control Panel will not really help - here is mine at the moment :-

======================================================================================================================

There is a much better way to check that your code is reporting correctly the instances, and that is

to use the facility in either Management Studio, or indeed Visual Studio ('VS') itself - if you use a modern

version of 'VS'.

Here is what Management Studio has to offer me on my PC :-

Yes, it looks as though the 'Express' version is not found by the code I have used.

To see more about using MS and VS for investigating Servers, and databases, see the next

sub-section.

Good Luck ;-0)

PHH - 3rd. & 7th. November 2016.


Use Management Studio to help us out

Use Management Studio to help us out

Use Management Studio to help us out

 Previous topic Next topic

Older guys, who have been around a few years have gotten to rely on Management Studio (MS) to keep us

right when it comes to instances of Server available on a PC, as well as making attachments to data files.

I have to say that the recent improvements in Visual Studio have meant that we can probably do more with VS

than we can now do with MS.

So I include this small subsection just for old guys and also to be complete in my eNotes content.

Lets find MS on my system - there are a few ways to find it and make a 'launch'.

Here is my Task Bar way of doing it :-

Notice the icon and tooltip near my mouse pointer above.

=================================================================

Or as above, we can just type 'Manag.....' at the Windows 10 Start Screen.

Click the highlighted item to run the application. (Or is it a double click ?)

If you have it on your start screen you may see something like this below :-

I tend to almost always use the Task Bar as shown below - make sure you launch it as 'Administrator'.

Which ever way you successfully launch (run) the application you should see something like

the following on your monitor screen :-

==========================================================================================

Notice that in the very top (title bar?) we see that '(Administrator)' is shown. This is what we need.

When I open the drop list I see very little compared to what I was used to in the past.

I seem to be offered only two instances options, even when I 'Browse for more'.

Notice below that

================================================================================================================

PHH - 4th. November 2016.


Use Visual Studio to help us out

Use Visual Studio to help us out

Use Visual Studio to help us out

 Previous topic Next topic

PHH - 7th. November 2016.


Connections strings

Connections strings

Connections strings

 Previous topic Next topic

Okay you guys, lets make some progress and get some positive results ;-0)

In order to connect from our code to a SQL Server and a Database, we need a 'connection string' :-

Making a Connection "String" :

There are a few ways we can connect our database to the SQL server. And there are a couple of ways

to even make our connection strings. By this I mean we have code 'alternatives' or different syntaxes

which both/all work.

In viewing examples on the web we will see more than one and so we need to be aware of the possibilities.

Here is one way, probably the most professional - checkout the details in full, carefully :-

=====================================================================================

Note that this above is a STATIC method and can be used just about anywhere to supply a tried and tested

connection string.

(The STATIC method has been placed in a Class called 'ConnStrings' - so the following code details should

make sense to you.)

Yes, the "SqlConnectionStringBuilder" class is very usable.

It looks a little bit long winded but it is clear to read and easy to alter and maintain.

And now we need to see how we can use it (the STATIC method) in our code - see below :-

=========================================================================

The code above produces at run time the following display :-

=============================================================================

Well, it seems to give us back what we put in the STATIC method code ;-0)

Now we can see how to use the defined connection string to instantiate a DataContext object :-

========================================================================================================================

The 'DataContext' class is VERY important to us when we do "LINQ to SQL" - this is the main way for us to open

up the world of SQL use, as opposed to Entity (Framework) use in later sections.

With a DataContext object we can tap into the world of SQL and its tables.

Lets see how we do this as a simple start, before we worry about named Tables and the likes - check below :-

==================================================================================================================================

==============================================================================================================

===============================================================================================================

PHH - 4th. November 2016.


Namespaces and Assemblies required

Namespaces and Assemblies required

Namespaces and Assemblies required

 Previous topic Next topic

Hi folks, without getting our selected assemblies right in our References section of the solution / project,

and without then using the correct Namespaces within these Assemblies, we will not get our code

to compile.

I have found the content of this sub-section by trial and error and using the Help Viewer 2.2 app.

Lets see what I have needed to get my test samples to run - well at least to start to run :-

[ .. checkout the lines 20 through 24 in particular .. ]

==============================================================================================

And now we need to checkout the References - see below :-

=====================================================

Lets now move on a step or two ...............

As I got more ambitious with my LINQ coding I needed some extra Namespaces.

Below I have shown what is now in use for my samples on 'LINQ to SQL' ('L2S') - check this

out carefully :-

==============================================================================================

And below we see the highlighted extra assembles that I needed to add to the default and standard

entries from the WPF template specification :-

=====================================================

Make sure you have all those shown above, both Assemblies and Namespaces, and you

should then get both 'LINQ to Objects' and 'LINQ to SQL' samples to work for you.

Any extras for 'LINQ to Entities' will be shown in that section, which is after this main section.

PHH - 4th. & 7th. November 2016.


The 'DataContext' class - and its uses

The 'DataContext' class - and its uses

The 'DataContext' class - and its uses

 Previous topic Next topic

The hub or 'bridge' between our SQL database and the related .NET business classes, is the

'DataContext' (DC) class.

At run time the DC object sits between the datafile within the database engine, and our instantiated

business class objects. Hence the DC completes the 'mapping' of relational data to .NET objects.

Get the DC right and we are laughing ;-0)

========================================================================

The 'hub' or central part of using "LINQ to SQL" (L2S) is the 'DataContext' instantiated object.

This instantiated object allows us to then query the database and get back results data sets, as

well as updating table data in the back-end database.

Obviously the DataContext object has to be instantiated with a suitable 'connection string'.

So a server instance, a MDF data file, and the correct file path, are all required to complete a

successful instantiation.

As well as getting the connection right for DataContext instantiation, we also need to create and

supply a suitable mapping for each Table we need to access.

So in our code we need a Class for each mapping - for example a .NET Class called Product which

will allow us to map to the SQL Table holding items of a product nature.

Note that not all the names of the table and its columns are exactly what we may wish to use in our .NET class.

For this reason we can define our own suitable names within the mapping via 'Attributes'.

Just for future reference, here below are the possible Attribute Namespaces :-

[ .. we will see some of these in use in our test simple examples .. ]

It would appear that I have just found a more complete list of these in MSDN - see :-

https://msdn.microsoft.com/en-us/library/system.data.linq.mapping(v=vs.110).aspx

Here are the first few, they include that for Column, which is very commonly used - check below :-

=================================================================================================================================================

Check out the following image where we supply the Mapping Namespace, as well as in line 41 use

the 'Table' attribute ( find out for yourselves which Namespace this is in ) :-

===============================================================================================

Lets now examine a simple but fully define Class below - it is called 'Product' :-

[ .. look for attributes and their parameters .. ]

=====================================================================================================================

===============================================================================================================

======================================================================================================

============================================================================

*** WARNING *** In the above code line 41 refers to a 'DataContext' but do not get this mixed up with what

we are talking about for L2S. Here the 'DataContext' is a property of the 'DataGrid' control in WPF.

The above is unfortunate, but we will just have to live with it !!

Lets move on a pace or two .............

Here shown below is the output of the result data set as bound to the 'DataGrid' control in our WPF form.

The data is returned from the 'GetProducts' function :-

==========================================================================

As you can see we have five columns of data items.

We can define our own DataContext class and provide properties which map to tables in the SQL database.

Here is an example I used years back written in C# :-

======================================================================================================

And below is how we instantiate an object of the new class - we need to provide the connection string :-

======================================================================================================

======================================================================================================

The input parameter (or argument) is a STATIC property returning a tried and tested string.

==========================================================================================

We now need to see in a simple example how we can do the same (or similar) for our DataContext class

in X# syntax / code.

PHH - 4th. & 7th. November 2016.


Designing our own 'DataContext' class

Designing our own 'DataContext' class

Designing our own 'DataContext' class

 Previous topic Next topic

Okay then folks, let start to do things properly.

By this I mean instead of coding out connections and mapping 'on-the-fly', or as we go along, lets

instead plan our project solution and design and create a specific DataContext class of our own.

We can design a DataContext ('DC') class to go along with our target SQL database. And make sure that

all the mappings from Table to our .NET business classes is all rolled together in the 'DC' class.

To help you understand what I am talking about lets view and study a simple working example I have made

specifically for this purpose - checkout the code in the following image :-

=================================================================================

Our above class is called 'StockDataContext' and is designed to 'sit' between the SQL database shown below,

and the .NET business data classes I have defined called 'Customer', 'ProductSimplest', 'PriceUpdate', and

'CustomerItem'.

Here is the very simple SQL database, as I have defined it :-

=========================================

As you can see, we have four Tables with the names as we discussed previous (above).

The column details are shown in the next image, check this out :-

==========================================================

And since we are going to be doing some real world testing with our sample app, we need to see the stored data

as we will be producing runtime data results sets.

Below is the 'Product' table details :-

==========================================================

And now the details associated with the 'PriceUpdate' table :-

========================================================

Now the details and data for the 'Customer' table :-

===================================================================================

And finally, the details and data for the 'CustomerItem' table :-

================================================================================

Please be well aware that all four of these Tables are VERY simple indeed, and that no relationships

or data constraints have been included in the SQL database design. I was trying to make things as

simple as possible, so that we can more clearly see the code related to the LINQ stuff, as well as

the L2S code structure involving the DataContext and the Attributes on the .NET business classes.

All the data I have added manually in Management Studio, and visually checked the details to then

hopefully have entered 'correct' values.

Lets move forward a step or two .................

Instantiating our DataContext object - of our own Class :

Before we can get any data retrieved from the SQL database we need to create a connection and then

use this connection to instantiate our DC object.

Here is some test example code which does just that :-

===========================================================================================================

Here is the displayed output at runtime :-

=============================

Now lets see the full test code for all of the four Tables :-

============================================================================================================

And here is what I see on my PC monitor :-

==================================================================================================

Notice that in lines 53, 57, 61, and 65 we are using a property of the DC which has already been assigned in the

Constructor, we are not using a Method to do the assignment in our code at the 'point of need' so to speak.

We could take this a step further and write / define DC methods to find and provide certain data sets.

Before we do this, lets first see how our project looks in the Solution Explorer (SE) pane.

=====================================================

I have made some sort of an effort to keep the code sections separated into sensibly named

project folders with suitably named files.

Here is a more expanded view :-

============================================

I am sure you can make a better effort than me to organise your code ;-)

But at least I made the effort !

Moving on a pace or two .............

Take a look at the following code for one of our business classes :-

[ .. note that the following is as simple as it can be and still have the major elements / sections required .. ]

====================================================================================================================

Notice above that I have not used private fields, and have kept the property definitions as simple as possible using 'Auto'.

This is equivalent to the C# 'get / set' approach, an example of which is seen below :-

===============================================================================================================

The Table and Column attributes seen in our X# code are required to map our .NET object through the DataContext object,

to our existing SQL Table in the Server's database engine.

So the DataContext object can be thought of as the object which facilitates (allows?) the mapping from SQL database

to .NET object, and back the other way as well.

So to get good mapping, or indeed any mapping at all, we need to define our business classes correctly and fully. We

must make best use of the Attributes, even if we are at first a bit unfamiliar with them.

*** Note *** please be aware that because we have a VERY simple set of Tables and simple Columns within them, we

do not need to use any or many complex Properties within the Attribute declaration. In real life examples this will be

different, and we will need to define classes more like that seen in the image below :-

========================================================================================================

The line of code highlighted below shows some common features for a typical table example. Note the

primary key and the fact that the key is generated by the database and not the user code :-

=========================================================================================================

And now that we have just gotten our heads into Attributes and their properties, we need to know of another

way to do the same thing - something I have used in the past with Entity Framework examples.

An Alternative to Attributes - Perhaps :

Some of you may think that using Attributes within the business class definition makes things a bit 'messy'.

Well, when I moved on to Entity Framework I started to separate out the attribute information into a configuration object. So

the business data class object stays clearer and cleaner, and all the attribute stuff can be placed together.

Just so you know what is coming in EF6/7 here is a working code sample of what I am talking about :-

=============================================================================================================================================================

Once we have the configuration we nee to add it to the registered list of configurations - check below :-

=============================================================================================================================

Now then, lets look at our own more slightly complex Table definition - it is more typical of what we will use.

Below we see a Primary key and a Foreign key as well as a mix of nulls being allowed and not :-

============================================

And often we can have more than one Foreign key - here is a simple example :-

==============================================

Okay guys, its time to move on, lets go and learn some more stuff in a different section.

See you there .............

PHH - 9th. November 2016.


Adding our own Methods to capture data

Adding our own Methods to capture data

Adding our own Methods to capture data

 Previous topic Next topic

Well folks, there are some data sets which we need more often than others, and these can be

rolled into the code definition for our DataContext class.

Take for example the list of all customers, and products - these should be common requirements.

Lets see how we can add some methods to our DC class to help us with these - so they are easy

to get in code when we need them in our project solution.

Study the following amended code to use the new methods :-

===========================================================================================================

Okay then, so we are using two methods to supply the results data set, but what are they like - their syntax ?

Study carefully the following details :-

[ .. I have collapsed some sections to make it clearer what is going on .. ]

==================================================================================

On lines 67 and 73 above we see the new methods. They obviously use LINQ to acquire the data.

These are what is used in lines 53 and 58 in the calling code of the previous image (shown above but one).

Going much further ..............

With the same approach of designing and creating specific methods to find specific data results sets we can

take things a lot further, by for example supplying a parameter input for the City in which a customer resides.

Let me write such a method and try it out to see what we get ......................

Yep! - we have something to view and test out.

Study the details in the following image :-

==========================================================================================

The new method accepts a string input and then makes a comparison in the query code.

Lets see how I coded the method call - check below :-

[ .. line 64 is where it all happens .. ]

============================================================================================================

Now lets re-examine the code I first wrote and tested, before I realised that my test input parameter (of 'London')

did not exist in the data - and that is why I got an empty data grid ;-0)

Study the following carefully :-

===========================================================================================

Yes, it works, particularly if we use 'Durham' in place of 'London' !

Below is how we action the method :-

==========================================================================================================

This all seems fine, and pretty straightforward - BUT - remember we may hit issues with data types !

For example if we wish to have a method which finds all the product items with a value greater than a specified

input parameter. If our price value is of type Decimal' then we need to code things carefully and correctly.

I will see if I can show you what I mean ........................ study the following carefully :-

====================================================================================================

Yes, we have an issue with the data type of 'Price'. We need to view the definitions in both the .NET class

and the SQL Table - check below :-

====================================================================================================

And now the SQL end of things :-

================================================

We had to define our .NET class in the way we did to make it compile and return results data. So we

have a type of 'Nullable<Decimal>'.

Everything else works except that we can't make comparisons with the operators =,<, and >.

If we are clever we think of writing a .NET Function in X#, but this causes issues as seen in the image

shown below :-

===============================================================================================================================

So from the above error message it would appear that we can't use .NET methods and X# functions in the query syntax.

We appear to have to write the query syntax as if it were T-SQL stuff used in a standard SQL statement.

We need to research some more, and ask a few colleagues.

To prove that our defined Function works OK we can study the following :-

==============================================================================================

'M' is for 'Decimal' and 'D' is for 'Double', see below for both in use :-

=============================================================================================

And now reversing the order of the two specified numerical values we see a different result - see below :-

===============================================================================================

And we can even go further with our tests - see the next image show below :-

==============================================================================================

Finally, we can push out tests to the limit and try a 'Null' in our comparisons.

Checkout the following detail carefully :-

=================================================================================================

==========================================================================

=============================================================================================================

And now for Something Quite Different ? :

To a query about our Customers, lets return a data set which is made from single string items (elements) and

that these are actually 'calculated fields'. Or in our current case, a string made by concatenating two other

string field items.

Lets call our returned items 'Fullname'.

And we wish to query a Table in which our customer data resides - BUT - the data values returned will not actually be

any one of the columns, or data fields of the table.

We will return a list of string items which will be made up from just some of the columns in the Table.

Let us examine the following image, in which line 104 does the business of making an anonymous class with a single

data property called 'FullName' - check below carefully :-

[ .. in SQL parlance, or 'speak', we would say this is a calculated field .. ]

=======================================================================================================================

Okay, the above works BUT we hit the problems of handling and passing anonymous Types, and as we saw in the 'L2O' or

'LINQ to Objects' this can get a bit tricky for the regular standard sort of a coding guy - like me ;-0)

Before we rush off to solve the ATs problem / issue, lets first see how we can use the virtual 'ToString()' method we wrote

into our Customer class - lets remind ourselves first :-

============================================================================================================================

So we can use this in our selection line - what we call the 'select' clause - check below :-

===================================================================================================================================================

I have to confess I do not like the idea of using a 'Foreach' loop to construct the result collection, in any way

shape or form ;-0(

After a couple more exploratory and learning images below we will see the cleaner, tidier approach to

providing a results list, or collection.

First lets see some output data from our current developing code :-

===============================================================================================

Well, we do get the right information Now lets do some tidying up :-

===========================================================================

But since in the above image code we are using the Type 'Fullname' and not an AT, we

can simplify things even further - check the following details :-

=============================================================================

Now then, the above looks much better to my eyes, and all I had to do was create the code

shown in the next image - below we see the small and very simple class of 'Fullname' :-

=======================================================

I will leave it up to you to add (or provide) a virtual method for 'ToString()' which outputs the 'Fullname' property value.

Now then, we had better have a look at the XAML script as we have been doing some data binding in order to show

our data results collection set.

Fits lets see the ListBox control and what we needed to do to get the names displayed / showing :-

=========================================================================================================================

The next image is of the data collection bound to a 'DataGrid' control - check it out :-

==================================

The column name is placed automatically as the XAML script (shown below) has the 'AutoGenerateColumns' property

set to 'True'. See lines 10 and 14 for these settings.

=========================================================================================================

So all we need more to make the display work, is to set the 'ItemsSource' to "Binding", and then in the

.NET X# code write something like the following :-

========================================================================================

PLEASE remember that the 'DataContext' property shown above, is quite different to the DataContext class

of the LINQ to SQL namespace.

So our sub-classed object called 'ourDC' and of type 'StockDataContext', is nothing much to do with the property

of the Control.

Remind ourselves of this :-

============================================================================

So we have a property of the WPF 'DataGrid' control called 'DataContext', and we also have a Class within the

LINQ to SQL Namespace which is called 'DataContext'.

We can use one without the other - either way round - or as we do here use both in the same solution code.

Just don't get them mixed up ;-0)

Lets look at our design surface in WPF for what we have been using to display our results :-

===================================================================

An finally, lets see the calling code to make this happen, but written in a way which makes

it more clear as to what is what, and what is going on.

Check this out carefully :-

===================================================================================

Yes, our Method defined on the 'StockDataContext' class of ours now produces a List.

The List is a typed list of - List<Fullname> which is much easier to handle and pass around our code.

Time to move on ....................

See you in the next section.

PHH - 9th. & 10th. & 11th. November 2016.


Compounding queries - how and what !?

Compounding queries - how and what !?

 Previous topic Next topic

Compounding queries - how and what !?

 Previous topic Next topic

We need to know about this topic as it does make our lives more easy if we do, and we use it when

appropriate.

It is much harder for many guys to do this in a SQL statement itself, as we need to know more about the

deeper side of the SQL query statement.

Lets start with a simple example.

===========================================================================================

==============================================================================================================

======================================================================

=================================================================================================

================================================================================================

===========================================================================================

===========================================================================================

====================================================================================================

======================================================

PHH - 11th. November 2016.


Problems and Issues - data types SQL v .NET !!!

Problems and Issues - data types SQL v .NET !!!

 Previous topic Next topic

Problems and Issues - data types SQL v .NET !!!

 Previous topic Next topic

Sorry guys - BUT - I have to say that we all can come up against coding problems when we start out

on the path to learn and use "LINQ to SQL" ('L2S').

And surprisingly enough, it is not the LINQ or related 'stuff' but in fact often the data types we have to

match up between our existing SQL tables and the .NET data types we have available to us.

This was always an issue in ADO.NET and if we don't use the 'Code First' technology provided by MS

in Entity Framework, then we need to do things manually - yes, ourselves.

Since I would suggest that any new work by us is done using 'EF6' or 7, we need not worry too much

about the possible 'wrinkles' that may exist with 'LINQ to SQL'.

I will show you in the whole section on 'L2S' how to get many and most things to work - AND - to high-light

the possible problems areas you are likely to face.

A Good Suggestion for You :

If you have a choice of Table existing in an SQL database, chose a very simple one to start with, and get you

going with L2S.

By simple I mean not too many columns, or fields. And also where the data types of the columns are simple

ones, like string, int, boolean, and datetime.

Keep away from money and decimal types for now.

Also, I suggest that your specified column properties in your SQL Table do not allow nulls.

This last requirement / specification my be a little difficult to apply, as many table columns are often 'nullable'.

'nullable' means can have a 'null' setting, no type value at all.

====================================================

========================================================

================================================================================

=======================================================================================================================

======================================================================================================================================

==========================================

======================================================================================================================================

================================================================================================

====================================================================================================================================================

===============================================================================================

=============================================================================================================================================================

==========================================================================================================================================================

========================================================================================================================

=========================================================================================================

================================================================================================================================

=========================================================================================

==================================================================================

=======================================================================================

=================================================================================================

=================================================================================================================

=====================================================================================================================================

=====================================================================================================================

PHH - 6th. November 2016.


Existing Tables - some more complex than others

Existing Tables - some more complex than others

Existing Tables - some more complex than others

 Previous topic Next topic

=================================================

========================================================

===============================================

=====================================================================================================================

============================================================================================================================

PHH - 6th. & 12th. November 2016.


Joining data from multiple Tables

Joining data from multiple Tables

Joining data from multiple Tables

 Previous topic Next topic

Okay then folks, JOINs in SQL were, and still are, a big part of using SQL databases. INNER joins and

OUTER joins and the likes.

However, for .NET programmers we can use Entity Framework 6 / 7 to do much of our data structuring within

our .NET applications. So JOINs do not need to play much if any part of EF solutions.

In 'LINQ to SQL' however, we do need to know at least how to do a JOIN, even if we use them rarely.

When we say 'JOIN' we mean that we can take one Table and connect it to another Table using a data

column in each to achieve the JOIN.

We may even JOIN a Table to itself, in a special case scenario, which is quite useful when you need it ;-0)

Lets look at some JOIN query syntax to see what this is all about.

In the following image, look in particular at the code lines 63 to 68, with line 64 being the crucial one for joining :-

==================================================================================================================================

In the above code we have joined the 'Customer' table to the 'CustomerItem' table.

This then gives us a maximum number of different data fields / columns of ten. We don't count the 'CustomerID' column more than once.

In the 'select' clause starting on line 66 we mix data values from both tables, in any order we choose.

Study lines 66 through 68 to see how these fields are mixed as an output anonymous type :-

===========================================================================================================================

We have in fact used only eight columns of data to be output, and two have been ignored - these are 'City' and 'Phone'

of the Customer Table 'structure'.

There is no reason for doing so, other than I wished to leave out one or two fields so that we needed to use an anonymous

type in our query syntax.

Oh! by the way, as we go through this example, see that line 35 shown below is no longer required, as Robert has included it

in a special define header file in the new build / compiler release :-

===========================================================================================================

Robert said this :-

I have added support for the XSharp standard header file (XSharpDefs.xh ) inside <Program Files (x86)>\XSharp\Include, and it contains the define:

#define CRLF e"\r\n"

So there is no need to do it the old way - and can't as there is already a CRLF defined.

Lets move on ................

Now then, if we can make a working LINQ query to do JOINs, let see what this looks like when the compiler / system

turns it into a genuine SQL statement with which to query the database.

Check this out all you 'SQL heads' !! :-

========================================================================================================================================

Notice that we are doing an INNER JOIN.

*** CARE *** this may not be so !?

If you wish to do an OUTER JOIN then simply reverse the physical order of the tables, and the result should

be the same as 'OUTER'.

*** Note ***

=====================================================================================================================================

Taking things Further - more JOINs :

PHH - 15th. November 2016.


Understanding JOINs in SQL Server

Understanding JOINs in SQL Server

Understanding JOINs in SQL Server

 Previous topic Next topic

Here is a useful web article.

It does not say anything more than can be found in the large red Bible on SQl by Paul Nielsen, but it

is well presented - check it out :-

http://www.codeproject.com/Articles/1137436/Understanding-JOINs-in-SQL-Server

Lets look at some of what Manjuke has to say ...............

===============================================================================================================================

Probably the most common JOIN is the INNER JOIN.

An business example of this will be to join each customer with his / her invoices. Where all existing invoices will be

joined onto the row data of the existing customer.

Customers without invoices will not appear in the results data set.

Study this carefully :-

=========================================================================================================

Lets move on ................

Now then, the VERY useful "LEFT OUTER JOIN", yes, it is very useful indeed.

With the LOJ we can answer data questions like... "which product lines did not sell any items last week / month."

and find out which customers did not place any orders within a specified time period.

There are lots of queries along these lines - i.e. similar to those two above.

Here is what Manduke has to say - the images are most useful ;-0) ...........

==================================================================================================

Okay then folks, why do we need a RIGHT Outer Join ?

Although the following image detail from Manduke explains the ROJ, it does not tell us a simple helpful

piece of reality !

If we are just joining two collections then the need for a ROJ can be changed to a LOJ by swapping over the two

input collections. Use the original primary collection as secondary, and the original secondary collection as

the primary.

*** CARE *** it is not that easy when we have more than two collections to join - so why not get our heads around

what a ROJ actually is - study the details below :-

===============================================================================================================

To put it quite simply, the 'LEFT' or 'RIGHT' refers to which collection has all of its rows / elements included.

LEFT is for Primary, and RIGHT is for secondary.

I will let you study the 'FULL OUTER JOIN' in Manjuke's article.

And the more difficult to get our heads around 'CROSS JOIN' is, as Paul Nielsen says .... we are rarely likely to need

it, but it can be useful for generating test data.

The difficulty with JOINs - if there are any - is that we need to know and understand our business requirements, so

that we actually use the correct (most suitable) JOIN.

It is NOT whether the code and query works, BUT, whether we get the correct results set for what we are hoping

we would get.

Make sure you do plenty of testing until you get an intuitive feeling for JOINs and how they are applied.

PHH - 21st November 2016.


Robert's Forum 'stuff'

Robert's Forum 'stuff'

Robert's Forum 'stuff'

 Previous topic Next topic

Although Robert sent this to me to help me with an INNER JOIN issue / problem, it is not a LINQ to SQL type

of example as it contains entities.

I had to change the structure of the code to make it a L2S example.

Here is what he sent - text then image :-

USING system.Collections.Generic USING SYstem.Linq CLASS Person PROPERTY FirstName AS STRING AUTO PROPERTY LastName AS STRING AUTO END CLASS CLASS Pet PROPERTY Name AS STRING AUTO PROPERTY Owner AS Person AUTO END CLASS FUNCTION Start AS VOID VAR magnus := Person{}{FirstName := "Magnus", LastName := "Hedlund"} VAR terry := Person{}{FirstName := "Terry", LastName := "Adams"} VAR charlotte := Person{}{FirstName := "Charlotte", LastName := "Weiss"} VAR arlene := Person{}{FirstName := "Arlene", LastName := "Huff"} VAR barley := Pet{}{Name := "Barley", Owner := terry} VAR boots := Pet{}{Name := "Boots", Owner := terry} VAR whiskers := Pet{}{Name := "Whiskers", Owner := charlotte} VAR bluemoon := Pet{}{Name := "Bluemoon", Owner := terry} VAR daisy := Pet{}{Name := "Daisy", Owner := magnus} VAR People := List<Person>{}{magnus, terry, charlotte, arlene} VAR Pets := List<Pet>{}{ barley, boots, whiskers, bluemoon, daisy} VAR query := FROM person IN People ; JOIN Pet IN Pets ON person EQUALS Pet:Owner INTO GJ ; SELECT CLASS {OwnerName := Person:FirstName, Pets := GJ} FOREACH VAR v IN Query Console.WriteLine("{0}",v:OwnerName) FOREACH Pet AS Pet IN v:Pets Console.WriteLine(" {0}", Pet:Name) NEXT NEXT RETURN

We can use the above but the following reads a little better ;-0) .............

====================================================================================================================

Lets try to make a suitable example from the above code from Robert.

We will first do the collections as objects in memory, then later move on to two Tables in a SQL database.

Joins are particularly good for joining SQL Table data, and hence are required in LINQ to SQL (L2S).

When we come to entities and L2E (LINQ to Entities) then we can get around the need for JOINs as such.

But we do need to know how to do them, and what they do for us.

Lets now look at my working sample code, and work backwards to the class definitions.

Here is what works for me :-

============================================================================================================

And while we are looking at results displayed, view code line 486 above, and then the equivalent line below.

Yes, the order of the properties in the 'select' clause is up to the coder/programmer to choose.

We don't have to put properties from the Primary collection element/item first, and then properties from item class in the

secondary collection - its up to us.

Compare below line 486 with that above :-

================================================================================================================

Okay then guys, Lets see how I have hard-wired the Person data, to create a list or 'Person' objects :-

==========================================================================================================================================================

And now we need to see how I made a list (collection) of 'Pet' objects :-

=======================================================================================================================================

The new 'collection initializer' syntax from Robert and his Team is really good - excellent in fact ;-0)

Now then, all that is left for us to do is examine in detail the short (rather simple) class definitions for 'Person' and 'Pet'.

Study the following two images carefully, and thoroughly :-

=============================================================================================================================

And now 'Pet' :-

====================================================================================================================

I realise that we could have made these even more basic if I had chosen to do so.

To summarize :-

Remember that we have made an 'INNER JOIN' and as such have no rows of data with NULL entries in any of the columns.

Also remember that we have being doing 'LINQ to Objects' (L2O) as our data was hard wired and did not originate in a SQL

data Table, or two.

We need to address the issue of making a LEFT OUTER JOIN in another sub-section.

We will also see the LOJ done with L2S - yes, real SQL table data.

PHH - 22nd. November 2016.


Left Outer Join - Pet, Person sample

Left Outer Join - Pet, Person sample

Left Outer Join - Pet, Person sample

 Previous topic Next topic

Let us remember that the main section of the eNotes that this belongs to is that for L2S, yes,

'LINQ to SQL'.

So we are to see a couple of SQL data Tables for 'Person' and 'Pet' joined in both the INNER (Join)

way as well as the LEFT OUTER (Join) way.

If we work hard we may even see a query in which we join three tables together. Well, at any road we

join the data rows from these three tables.

Let us now roll up our sleeves and see what we can achieve - remember, this LINQ stuff just gets easier and

easier, the more practise we have and do.

PHH - 22nd. November 2016.


Three Tables two Joins - Pet, Person, Type sample

Three Tables two Joins - Pet, Person, Type sample

Three Tables two Joins - Pet, Person, Type sample

 Previous topic Next topic

Lets do this sub-section from "finish to start", or as we UK guys call it, "Back to Front"!

If we start with the X# query code, that is from my currently working example, we will see very quickly

and easily how to make two joins work - with the potential to make many more if required.

Here is what has just worked for me on my office desktop PC - study in detail, carefully :-

==========================================================================================================================================

[ .. the WHERE clause on line 478 filters out two rows of data values .. ]

Notice in lines 476 and 479 we have two JOIN clauses.

This is based on the Person-Pet sample that Robert posted in the X# Forum. I have added a third Class called 'PetType'.

So the above example starts with the Pet collection and joins the Person collection, then does a further join to the

PetType collection.

This is a L2S "LINQ to SQL" sample and so we have three Tables in our database called, Person, Pet and PetType.

Here are the Tables shown in management Studio (MS) :-

===============================================================================================================================================================================

Okay then guys, before we move on to explain all the working details of the Person, Pet, PetType sample,

lets see a much more complex multiple join, from a real life working application to process Civil Engineering

field data from 120 temperature sensors and a few other input sensors for weather.

==================================================================================================================

I would see to me that we have five JOINs in my working C# code from years back.

Let move on with our Pets etc. ..............

We need to see the three Class definitions - check below :-

=============================================================================================================================

And now 'Pet' :-

====================================================================================================================

And now 'PetType' :-

=====================================================================================

Remember that the attributes are required for the mapping of the SQL Tables to the .NET Classes.

Here are our mappings in the DataContext sub-class of ours :-

[ .. notice some of the relevant namespaces being 'used' .. ]

======================================================================================

In the image above it is lines 48 through 50 which maps the SQL Table to the .NET class.

And then we need code in our DataContext definition to set the data - as seen below :-

===================================================================

We then need to populate the properties the SQL data. We did Persons and Pets previously,

but new to this example is PetTypes, so here is the code :-

================================================================

And we can easily test this by a quick bit of data binding in our existing WPF data grid.

Check this out below :-

==================================================================================

Okay, so we can see our data from the SQL table called 'PetType'. And yes, we could, or should, have made

some columns/fields enums, but I tried to keep everything as simple as possible.

Lets move on ..............

So now that we have three collections returned from the SQL database, we can write a simple query to use

them as seen below :-

[ .. remember that the query does not actually get 'run' until the returned data is actually needed for use .. ]

[ .. so below it is line 524 which causes the query to be run against the database .. ]

===================================================================================================================

In lines 520 and 521 above, the order of the matching / comparison matters a lot.

The first item of the comparison in related to the earlier collection and the last (or second) item of the comparison

is related to the collection being 'joined'.

The compiler will soon let you know if you get this wrong.

Now then folks, we need to see the code for the collection properties assignment :-

=============================================================

Notice that we can use the business objects themselves, not just their properties. Check the

following image to see how we can use the business objects themselves as properties in a newly

declared three property anonymous type :-

==========================================================================================

As you can see above, we get three columns, one for each business object property.

Since the three columns are for Objects and not values, we have printed out what we defined as the

virtual 'ToString()' method defines - see the next image to see what I mean (line 143 determines

what we see in the 'pt' column :-

==========================================================================================================================

And here is the method relating to the content of column 't' :-

========================================================================================================================

In the next sub-section you will see how we change the code slightly to carry out an OUTER JOIN.

Outer Joins are important to solving very useful problems / questions, so don't ignore then.

We will also see in the next section how to be in control of which collection elements are in scope

for our use within the query code.

See you in the next section ................

PHH - 22nd. & 24th. November 2016.


Collection elements in scope - which and where

Collection elements in scope - which and where

Collection elements in scope - which and where

 Previous topic Next topic

In the last sub-section we were carrying out an INNER JOIN between three Tables. And then moved

on to make a LEFT OUTER JOIN, twice over - as seen by the extension method use of 'DefaultIfEmpty'.

[ Its really the OUTER Joins which can give us most grief when needing to get the correct element scope. ]

The query therefore had two JOINs as such.

Although it is easy enough to code the query so that it works, and does the join, it is another

matter when it comes to accessing properties to specify / define an anonymous type. Depending on how

we use the X# syntax we get restrictions (or limitations) on the 'scope' of the properties being used.

We really do need to spend some time thinking on this problem / issue as it is a real 'show stopper' when

it hits you. I know, I have been there last week, and although Robert pushed me in the right sort of

direction, it was with research and experimentation which won the day - did the trick.

After much trialling and testing I have come up with a simple rule - it is shown in commented green below :-

================================================================================================================

When we look at a query related to JOINing, we often see 'FROM' clauses.

In my working example shown above we have lines 548, 550, and 552 which are FROM clauses.

Just after the word 'from' we have collection items / elements, and so 'pn', 'iPP', and 'iPPT' are those we

need to study.

'pn' is an object of type Person, 'iPP' is an object of type Pet, and 'iPPT' is an object of type PetType.

Since these follow the word 'from' we can use them directly in the code for the anonymous type (AT) as

we see in line 553.

The results found by this query are seen below (for the data I have in the SQL database) :-

================================================================================================================

In line 553 shown above, we see 'pn', 'iPP' and 'iPPT' used as class object with which we can access their Properties.

Yes, no out of scope error messages from the compiler.

Okay then, if all these are in scope which are the elements that we can't or mustn't use ?

The answer is quite simple it is 'pt' and 't' - which come immediately after the 'join' word on lines 549 and 551.

This is most confusing at first (this is what got me) when the equivalent code for a INNER JOIN looks very similar

but uses the very elements which we can't for an OUTER JOIN.

An example will show exactly what I mean - check this out :-

====================================================================================================================

Above we see that we use the one element after the single 'from' clause word, but need to use 'pt' and 't' after the 'join'

clause word.

This is exactly what we can't do when we create an OUTER JOIN query - lets see the errors - check below :-

===============================================================================================================================

Yes, the use of 'pn' is okay, as we would expect - BUT - not 'pt' or 't' - check the following :-

===============================================================================================================

For those of you who are SQL guys, with some years of experience in querying, it may help if you see the actual

SQL query statement made 'under-the-hood' by the compiler - for both INNER and OUTER examples.

First the INNER example :-

===================================================================================================================

And now the OUTER example :-

=========================================================================================

So hopefully, some of the above detail will help you in your coding of L2S and joining etc., etc..

However, before we leave this sub-section we need to see a few other ways we can declare our

anonymous type result set, and even not use an AT at all.

I advise you to look at a few different ways of forming the results set / collection, as we often need

different solution types at different times - we need to be flexible.

Lets now do some experimenting - here is a first trial :-

========================================================================================

As you can see in the image above, the contents of the 't' column are not as nicely displayed as in the other two.

This is simply because we have not defined a virtual method for 'ToString()' for the class PetType.

Lets change that now - how about this ? :-

========================================================================================================================

And now when we run the test app we see an improvement - study this :-

=========================================================================================

And we can improve the Pet column too - see this :-

==========================================================================================================================

Okay then, we understand the formation of an anonymous type with three properties, but what are each of these

Properties ?

One thing we can do to show to ourselves that we understand what is going on, is to define a new Class of our

own which has the same structure as the AT we declared 'on-the-fly' above.

Here is what I have done to get things working just fine here in my office :-

===========================================================================

I usually like to include an empty Constructor in my classes, as there is often places in .NET and WPF

where it is needed 'under-the-hood' - the system using it and not my code.

If we have a Constructor which takes all three property values we can instantiate in our query like that code

shown below :-

[ .. see line 523 .. ]

========================================================================================

Obviously, if we use the Constructor that takes the three parameters as shown, then we MUST make

sure that the order of these parameters is correct.

Probably a better way to 'select' is to use the new initializer syntax of X# and do as line 523 shows

below :-

======================================================================================

Note that the order of the parameters within the initializing braces does not matter, as we are

specifying the Property being assigned.

Now then guys, one of the benefits of using our own class for results elements in the results collection, is

that we can make a strongly typed List of the results.

Check this out below :-

[ .. lines 525, and 526 .. ]

=======================================================================================

Once we have a strongly typed list we can pass this on to wherever we choose and we don't have

to worry about how we handle it later in our code, as it is not an anonymous type.

Time for you to go and create your own test samples - get a feel for how all this stuff works.

See you in the next section ................

PHH - 24th. 2016.


Grouping data; row information

Grouping data; row information

Grouping data; row information

 Previous topic Next topic

Okay guys, lets have a little fun, let's enjoy ourselves ;-0)

I always find I enjoy myself coding when I feel as if I know what I am doing - in control so to speak !

Grouping now feels good to me, now that I have had some practice at it.

With a few good examples to copy, you can get well in control of 'Grouping' as well.

The lack of 'blue' colour in 'where', 'into' and 'select' are explained below the image ...........

Grouping is all about rows in the data - and amalgamating these in some way or another.

Remember that the rows in a collection after the grouping process does not have any data that relates back

to any individual row, only the Key, which would do so if there was only one row for a particular key value.

Moving on ..................

Have a look at this simple Group example for L2S ('LINQ to SQL') :-

=========================================================================================================================

[ .. as I am using a version of the compiler out of sync with my Visual Studio integration .. ]

[ Robert said this :- And w.r.t. the editor colours: the parser inside your compiler is a few builds ahead of the parser inside your VS integration. ]

Lets us see what our data looks like from Management Studio (MS) :-

===============================================================================

In the details shown above you can work out for yourself what you think the results of the grouping should be.

Below we have started to upgrade the query code to provide some group statistic type values (well, one at the moment) :-

========================================================================================================================================================

Above we have used a Lambda expression to find the 'sum' of the group total values.

Now lets see if we can add a few more - check the following details thoroughly, first the results display :-

And now the code which generated the SQL query statement that the runtime system sends to the SQL

data engine :-

===================================================================================================================

Above you will actually see this under-the-hood generated SQL query statement.

Lets copy it out and see what we get when we apply it within MS (Management Studio) :-

====================================================================================

The contents of the TextBox control is highlighted and copied - see above :-

And now the pasted text in a new query window (with long lines split into two :-

===========================================================================================================================

Note that the .NET variable @p0 has to be replaced by a hard coded one , that is '1'.

And if we re-run the query in MS without the 'HAVING' clause - here in LINQ query code (that is the last WHERE clause),

we get the following results :-

===========================================================================================================================

Only the highlighted text is used as a query - MS users will understand what I have done.

So lets move on a further step, and add an Average field / column - study the following :-

=========================================================================================================================

*** Remember *** the colouration of the code and reserved words is not as it should be when all is okay with the parsers.

PHH - 19th. November 2016.


The user's Data Classes

The user's Data Classes

The user's Data Classes

 Previous topic Next topic

Because we are using LINQ to SQL ('L2S') we need to make a mapping between the SQL Tables

we wish to use, and the .NET classes to which these Tables refer.

In L2S we simply work with flat Tables, and have no entities within our querying code, or related code.

So the .NET classes to which we map do not have properties which are themselves business class

object collections which are mapped to other Tables.

For such mapping as described above we need to use LINQ to Entities and the Entity Framework version

6 or 7.

We will use the versions of the Person class as an example of what we need and what is too simple for

us to use with L2S.

Here is the simplest form of a 'Person' business class :-

=========================================================

The '0' or zero, is there simply because may main class for example use is called 'Person'.

Lets see this more elaborate class in the following image :-

==============================================================================================================================

Now then folks, we see attributes in our code - these are on line 85, 88, 89, and 90.

Attributes come at the start of a code line and so the Table attribute (as it is shown) needs a semicolon line continuation

character added to it.

Notice that each Property also needs a Column attribute, even if it is as simple as " [Column() ] ".

In the next example of a business class of mine we are using Product as our example.

By this I mean we have a SQL Table named 'Product' as well as a business class of our own coding

which is called 'Product'.

In the next image we are needing to look at the data Types of our defined Properties.

Notice that we are starting to use 'nullable<>' types - versions of our standard data types.

It is crucially important (VERY) that handle nulls and our types correctly.

From the image shown below try to match up the properties with the columns in the subsequent image

from the Management Studio IDE - check this out :-

======================================================================================================================

Now we need to compare the above property types with the details shown below.

Note that 'string' types can be 'null' anyhow and so we don't have to declare them as nullable<> types.

As you can see from the table details, we can have null associated with all columns.

==============================================

Also we need to realise that 'smallmoney' types in SQL equate to 'decimal' type in .NET.

We must get our types correct for the mapping to work.

This is easy if we use Code First within L2S, as we can then have the L2S system make our database for us, using the

table (business) classes we define.

However, there is no getting away from it that we do need some knowledge of SQL, we can't just keep our fingers

crossed and hope !

Lets move on ..........

Branching out a little :

There are other times when we need our own business classes, and one important time is when

we wish to use it in the select clause of the query.

Here is a simple class I used earlier this afternoon with the Person / Pet example from Robert.

==========================================================================

And here is an example of how to use this data acceptance class.

=======================================================================================

Yes, we have only the simplest of class definitions, since we don't have a SQL Table to map to, then

we don't need attributes or the likes.

It is worth knowing that if you use simple defined classes in place of anonymous types, then we

could be saving ourselves some issues further down the line, when we wish to move our collections

of data around our code, as input / output to and from Methods, or objects as parameters.

For our own classes we know exactly the type, so no problems there.

Okay guys, time to move on, see you in the next section .............

PHH - 4th. & 24th. November 2016.


Mapping SQL Tables and user Data Classes.

Mapping SQL Tables and user Data Classes.

 Previous topic Next topic

Mapping SQL Tables and user Data Classes.

 Previous topic Next topic

=====================================

==========================================================

=======================================================================================================================================

=======================================================

========================================================

PHH - 4th. November 2016.


Using 'Attributes' in our Class definitions

Using 'Attributes' in our Class definitions

Using 'Attributes' in our Class definitions

 Previous topic Next topic

Well folks, many of us are not very used to using 'Attributes', either much, or at all.

But with 'LINQ to SQL' (L2S) we must use them in order to get the technology to work for us.

They are not difficult to use or understand at a basic user / coder level. And, there are plenty of

working examples out there, they are just in C#, so we need to know how to read them, and also

how to code our solutions in X# syntax.

Here is a start to finding out something on 'Attributes' :-

https://msdn.microsoft.com/en-us/library/system.data.linq.mapping(v=vs.110).aspx

And here is some of the content at the above link (URL) :-

===================================================================================================

Above is just the first of many classes in the mapping Namespace.

There are actually 22 in all currently.

Here are a few important ones - meaning a couple we are most likely to have to use frequently.

The 'Column' one is a VERY commonly used attribute. Check details below :-

===============================================================================================

And now if we drill down to the 'Column' details with this link below :-

https://msdn.microsoft.com/en-us/library/system.data.linq.mapping.columnattribute(v=vs.110).aspx

We see the following details and information about the ColumnAttribute class :-

======================================================================================================================================

Yes, we have twelve (12) properties of the Class and we also have an empty constructor.

Lets now see some X# syntax with use being made of Attributes, to good effect :-

[ .. checkout lines 73, 84, and 95 to see the Column attribute in action .. ]

======================================================================================================

As you can see the code compiles and runs and the display shows the results set.

Here is another common one, the 'Table' attribute being used in a C# example :-

============================================================================================

Note that some properties in the Column attribute definition are not as commonly seen as some others.

We need to gradually side into using Attributes, doing what we have to do first, then finding the 'richer'

stuff later on ;-0)

Here is another Class which may prove useful in the future :-

================================================================================================

And once again an empty Constructor exists :-

=============================================================================================================

Some of the following Properties look as though we may need them sometime soon, ones like 'IsForeignKey' for example.

As yet I have not used in real code this particular class.

===============================================================================================================================================

And as an example of the above class, here is some C# code :-

==================================================================================================================================================

I need to do some more work and research on the Association class.

Lets move on .............

Multiple Attributes ? :

Well guys, I am asking this question of myself as much as anything.

I am not even sure if it makes sense to be able to specify more than one 'Attribute'.

We know we can provide many properties for one Attribute, as we have seen above (and below).

From the web searches I have done, and the evidence that I have found, it would seem the we only can

provide one Attribute - see below for a typical C# sample, from CodeProject :-

==========================================================================================================

We can write something similar in X# as seen by a snippet from a working test example of mine :-

=========================================================================================================================

Note that the four lines for Class and Properties are written all on one line, and if we need to rearrange code

to suit our personal style then we need to add a semi colon (;) in order to have a line continuation.

Here below is a code layout that I prefer and tend to use most times :-

=========================================================================================

Notice that in the C# example 'Column' is used a couple of times without any properties being defined.

So this means we can have 'empty' Attributes used.

==================================================================================================

Okay then guys, lets explore the Column attribute with some variations in how we code the Constructor.

In the image below we see working code which had line 83 in operation previously.

Now I have experimented with extra lines 85 and 86 - both of which work for our data and example :-

============================================================

So the syntaxes '[Column()]' and '[Column]' both work for us in our example.

However, how do we know that the attribute definition is actually having any effect at all ?

Shall we comment the previous line 86 and see what happens ? Check below :-

===========================================================

Oh! - we have some corruption in our data results set.

We need to put back the Column attribute in order to get all the data we need. So we also need

to remember to always provide the Column attribute to every property in our own business classes

which we require to be mapped to a column in the SQL table.

Other properties within the Column attribute constructor depend on our business data circumstances.

*** Remember *** we need to be careful over the positioning of our commented code, and the line

continuation character (colon) as seen below :-

===============================================================================================================

Move line 85 to 88 to solve the problem - or remove the comment lines altogether.

Good Luck with your sample / example creation and testing.

PHH - 5th. November 2016.


Our first simple working example

Our first simple working example

Our first simple working example

 Previous topic Next topic

Okay then guys, lets start and get some working results returned from a simple 'LINQ to SQL' query.

We are best to start with as simple an example as possible, using data from only one Table in the SQL

database - lets use the 'Customer' table.

In Management Studio (MS) we can see the 'Customer' Table - check below :-

================================================

Yes, the 'Customer' table is just one of six that is currently in the database called 'Stock'.

If we expand the tree structure we can see important details of the columns within the Table structure.

Check these details :-

=================================================

Okay then folks, lets code our first simple query in L2S based on this simple Table - check the following :-

=============================================================================================================================================================

In the above image, code lines 539 and 540 form as simple a query as we can have in 'L2S'.

The returned results set is also shown to the left of the code being executed.

Lets stop a moment to see the actual SQL query statement that is built for us 'under-the-hood' by the

compiler / runtime system.

==============================================================================

Okay - we get some results which seem to make good sense, but what about the DataContext class

we need to define for ourselves ? How does it look and how do we use it ?

Here is the relevant part of my code for the "StockDataContext" class I have defined :-

==================================================================================

[ .. if you wish to see more about the 'Connection String' for line 53 above then see the

child section from here .. ]

Notice above that we have a property called 'ourCustomers'.

This property is going to be mapped to the Customer table.

Here is how we use it in the initialization stage :-

=========================================================================

And now we need to examine the other end of the mapping, that is the Customer class definition.

Check out all the details thoroughly :-

==========================================================================================================================

The attributes are necessary to make the mapping from Table to .NET class work.

Now then, once we know how to make queries work for us, we can define a class method to return the

full set of Customer data.

Here is something I have here, and have used in other test samples :-

====================================================================

We will discuss in a separate sub-section, the type of the collection returned from queries. Here,

above, we are returning a strongly typed list, where the collection items / elements are Customer

objects.

Lets move on with our simple example ...........

Let us now add an extra line, a 'where' clause - see the following image :-

============================================================================================================================

Yes, the 'where' clause generally acts like a filter, and fewer rows are passed in the results set which is returned

by the database engine.

Remember, 'where' restricts rows, and 'select' restricts columns (or fields).

Lets now go and add a further extra line to the query - lets sort the rows :-

============================================================================================

Before we go and examine the row set and its order, lets take a moment to study the above SQL

query created by the system from our .NET coded query syntax. Check above :-

So here are the rows in the returned results set :-

==========================================================================================================================================================

Notice that the rows above are in order of postcode Z- A.

Lets now filter on a different data column - and lets try handling some 'null's.

===========================================================================================

Okay, I get your comment - it is a bit silly to filter out only rows with null for the post code and then sort

them by the same column !

I leave it to you to change the column for sorting to a more sensible one for the data being handled - like

the City field in order A - Z.

Since we have the results and images for the silly ordering on PostCode, we will just have to go with it

for now.

Checkout the displayed SQL query which we can copy from the TextBox control and paste into Management

Studio as a query to execute.

Check the display first - this below is a TextBox in WPF :-

========================================================================================================================

And highlighting the query ....................

==============================================================

We can then copy and paste as shown below :-

=================================================================================================================================

Notice we get the same results set in MS as we did from our .NET X# app.

PHH - 4th. & 26th. November 2016.


Connection String

Connection String

Connection String

 Previous topic Next topic

In order to use 'LINQ to SQL' we need a suitable connection string.

'Suitable' means it needs to be correctly formed, and with the correct information included.

Here is the connection string for my office PC system, and for my SQL Server instance, as well as

database file path, etc., etc. :-

====================================================================================================

There are other ways to provide a connection string but this is as good as any I feel.

See you in the next section .............

PHH - 26th. November 2016.


A more complex working example - return 'singles'

A more complex working example - return 'singles'

A more complex working example - return 'singles'

 Previous topic Next topic

Okay guys, we are now going to extend our simple query to cover the case where instead of

a collection being returned from the SQL data Table we get a 'single' result.

In our case the 'single' will refer to a single Customer object.

Take a good look at the following working code image :-

========================================================================================

Yes, we are trying to find one, and one only, Customer who has a 'null' postcode entry.

This approach relies on using the extension method 'FirstOrDefault()' and so the body of the query must be

enclosed in round braces.

If we wish we can further narrow our search down to include a City entry / value, in this case 'Paris'.

Check out the extra line at 579 :-

==========================================================================================

And now it would be nice to cast our single result back into a Customer object - for ease of use elsewhere,

and a few other good reasons as well.

In the image of the working code shown below, study in particular lines 584 and 585 :-

==============================================================================================

And now that we have a single Customer object we can then place it into a strongly typed list.

Below, checkout lines 589 through 592 to see how we handle our Customer object 'item' :-

====================================================================================

Okay the folks, we have been a bit over focused on Fabrice and Paris, so lets see if our same query

does work with 'Gloucester' instead of 'Paris'.

You need to study the data to see this is correct :-

======================================================================================================

Well, this time our single result is a Customer object based on "Dai Darkin" details.

See how it is 2nd in the SQL data returned below :-

=====================================================================================================================

So here is more confirmation - see below :-

===================================================================================================

And finally, some image proof that the now single item in the List object can be seen when

the list collection is data bound to the DataGrid control - see below :-

================================================================================

[ .. note the syntax on line 590 - thanks to Robert and his Team .. ]

Remember that it is best to keep working in complete objects of our defined business classes,

rather than trying to isolate just the values we may be after.

The modern .NET way is to completely work in business class objects.

It is now old fashioned and limiting to deal in single property data values. This is part of the old

world where we also dealt in columns and rows from files like DBFs.

Now we need to work with Objects, and Business Objects that we define. When dealing with

objects we can then easily work with collections of such objects, and this is where LINQ plays

a big part in our coding.

I committed myself to LINQ almost six years ago, and have never looked back - previous to that

I had been a committed ADO.NET man.

Yes, this also means you will have to give up your love of DataTables ;-0) Sorry !!!

Lets move on ...................

PHH - 6th. & 28th. November 2016.


'Persisting' - Saving back to the Database - 'changes'

'Persisting' - Saving back to the Database - 'changes'

'Persisting' - Saving back to the Database - 'changes'

 Previous topic Next topic

Lets get this right (correct) from the start, changes are saved back to the Database, and not the

individual tables.

This means that the methods to do with changes are on the DataContext object, not a Table object.

Changes can be marked as for 'submitting' or not. If no effort in code is made to mark the changes to a Table for

submitting, then even when the 'SubmitChanges()' method is called then these changes will remain locally, but not

be included in the back-end database.

When you have studied the samples shown below you will know exactly what to do.

Okay then folks, lets see the X# code definition of a new class called 'Invoice'.

This .NET class will be mapped to a SQL Table called 'Invoice', and I will make this in my 'Stock' database

from within Management Studio (MS).

We can look at the 'Code First' approach in a different sub-section.

*** Note *** The following is true for any Table we have and use in 'L2S'.

====================================================================================

In the image shown below look out for the attributes - the one for 'Primary Key' is very important :-

==========================================================================================================================================================

Yes, it would appear that in order to create (or add) a new row in an existing Table there needs to be a

'Primarry Key' defined.

Here is what I made using Management Studio :-

==========================================

So why don't we see how to use the Invoice class to code a new Invoice object and add it to the Invoice

Table in the Stock database.

Checkout these details below :-

==========================================================================================================

Line 557 sees a new Invoice object instantiated.

Line 560 above shows how we can add an object to the Invoices collection, and have it ready for changes to

be sent back to the database engine. This updated collection list is displayed in the data grid of the WPF form.

Finally above, the line 562 forces the changes to be actioned at the database engine.

Lets see if we can now query the DB via Management Studio and see the new row in the Table of invoices :-

======================================================================================================================================

Yep! - looks like an easy way to add invoices to the Table.

The benefit is that we get compiler checking rather than send a query string directly to the database engine.

Here is another new invoice object - check it out ............... :-

===================================================================================================

And here is proof of the coded 'action' :-

=========================================================================================

We had better check-out the X# code needed within the definition of the data context class of

ours - the one we called 'StockDataContext'.

Here is what I have working for us :-

[ .. I have collapsed some of the basic lines which are not related to what we are currently doing,

and studying .. ]

===================================================================================

There is nothing special or unusual with what I have done above - all standard 'stuff'.

Lets now add a new Method to the 'StockDataContext' class, one to find all the invoices.

Check this out below :-

==================================================================

Testing this we can try the following code :-

=============================================================================================

Notice that the new method does work, AND that the last row shows that it has been added in code,

since the digit display in the bottom right hand corner is different to those other in the same column above it.

So the last row has come from code and not from the database query retrieval.

Lets see what giving an new invoice an ID of 4 does - 4 has already been used - check this out :-

====================================================================================================================

As you can see above, the value of the InvoiceID seems to be being ignored. And the new value of '6' has been issued by the

inserting system.

If this is the case and any value supplied for 'InvoiceID' is ignored and over-written with the next value issued

automatically, then we ought to be able to leave out a value (any value) altogether - lets try it below :-

[ .. check out line 561 in particular .. ]

============================================================================================================================================================

It looks as if the incrementation is being done by the LINQ to SQL techology in .NET, before the changes are sent to the

SQL database. Either way we do not need to issue a value for 'InvoiceID'.

The simplest way to see and view our Invoices is shown in the following image :-

============================================================================================================================================

Okay guys, we have done enough for one small sub-section.

Lets move on, see you in the next section ......................

PHH - 26th. & 28th. November 2016.


Updating existing rows / object items

Updating existing rows / object items

Updating existing rows / object items

 Previous topic Next topic

*** CARE *** before you do any testing on CRUD (create, update and delete) make sure the Table you are

to use for your testing has a Primary Key.

Here is something which just caught me out :-

===========================================================================================

So do NOT forget what is shown above !!! Tables must have PK (primary keys).

Think about this from the standpoint of a SQL user / coder, and it makes good sense.

==============================================

So if we can't use Customer as it is (has no PK) then we will need to try Invoice as this

Table does have a PK - check below :-

[ .. for testing it is too much trouble to drop and recreate the Customer table with a PK defined / declared .. ]

===============================================

So we will use Invoices and the Invoice table.

Okay guys, in the parent folder from here we saw how to insert a new row into a SQL Table.

A new row was a object based on our Table - like 'Invoice' (or any other Business Object with a primary key).

But what if all we wish to do is take one row / object and make a small change to one of its

property values (column values) and then persist this changed data - back into the back-end

database (or table) ?

Well lets give things a try and make a small test example.

=================================================================================================================================================

==========================================================================================================================================

=======================================================================================================================

=================================================

*** Don't *** try to update / change the PK value !!!

PHH - 28th. November 2016.


Deleting existing rows / object items

Deleting existing rows / object items

Deleting existing rows / object items

 Previous topic Next topic

*** CARE *** before you do any testing on CRUD (create, update and delete) make sure the Table you are

to use for your testing has a Primary Key.

Here is something which just caught me out :-

===========================================================================================

So do NOT forget what is shown above !!! Tables must have PK (primary keys).

===============================================================================

Lets use Table named 'Invoice' as this does have a PK - see below :-

=========================================================

======================================================================================================================

==================================================================================================================================================

=======================================================================================================================

========================================================

===============================================================================================

PHH - 28th. November 2016.


Creating a new Database - 'Code First'

Creating a new Database - 'Code First'

Creating a new Database - 'Code First'

 Previous topic Next topic

Here is a straightforward introduction to the many subsequent sub-sections of this main section.

The term 'Code First' is probably more correctly applied to the 'Entity Framework' technology.

However, it seems to have generally been accepted as the approach by developers in which they

define the .NET classes for the Tables in a SQL database, before the actual DB exists on disk.

From the code definition the SQL database is created, almost like 'magic' !

If we design and define a class for each Table we require, then we can create the database from

code quite easily, as part of the 'LINQ to SQL' technology.

Yes, and once again it is more than helpful if we (the developer) knows some of the basics of the

underlying SQL requirements. How a database is structured and related etc., etc..

There are software tools to do a lot of the 'leg-work' of both using an existing DB, as well as carrying

out 'Code First' - BUT - I feel that it is best for our knowledge, and skill development, if we do it ourselves,

manually. Then we should understand more about 'L2S'.

Sometimes in web articles this approach is called 'dynamic' database creation. So the implied

situation is that the code is present in the .NET app as the dynamic process is started.

Dynamic - "Code First" by any other name it seems to me ;-0)

*** REMEMBER >>> This is a fun way to create and use a SQL database.

We can do quite a lot with 'L2S' and also learn a great deal while having fun ;-0)

However, if we need to do a real task, make a business application, we are probably best advised

to look to Entity Framework (version 6 or later) to do the job for us and not 'L2S'.

We need to remember the chronology of the technology development. Microsoft made available 'L2S'

before they had perfected the EF technology, and also later versions like 6 and 7 etc. were much more

solid and robust to use.

So lets move on to the first sub-section to see what we can learn.

Here is an image of the new project / solution we are going to create - check the following details

most carefully - [ ..I have split the solution into suitable folder sections .. ] :-

==================================================

We will study the folders in turn as we progress through this section on 'Code First'.

See you in the next sub-section ................

PHH - 29th. November 2016.


Mapping - ORM, Object Relational ...

Mapping - ORM, Object Relational ...

 Previous topic Next topic

Mapping - ORM, Object Relational ...

 Previous topic Next topic

Mapping - Relational Database to .NET classes :

As part of the new DB definition / declaration we are carrying out a 'mapping'.

"LINQ to SQL" can't work without us making a suitable 'mapping'.

We need to remember this as our primary (main) aim in setting up our test app.

If we get the mapping right (using Attributes on our Tables and Database, then everything

will work just fine.

We do need to know a few things about SQL in order to get all our stuff to work.

Firstly we need to provide a 'Primary Key' column in each Table we define, if we are then to be able

to change and update the data stored in the back-end database.

Not doing the above is a real 'gotcha' later on.

'ORM' stands for "Object Relational Mapping".

The SQL database is the 'Relational' bit, and the .NET business class code is the 'Object' part.

For the simpler version of L2S mapping, we have a business class object mapping to a data row

in a single Table within the database. For example a 'Customer' object to one line (row) in a

'Customer' table.

PHH - 29th. November 2016.


Naming the new Database - connection string

Naming the new Database - connection string

Naming the new Database - connection string

 Previous topic Next topic

What we need - a named Database :

Okay then folks, we will need to name the new database, and then design and name a few Tables.

The naming of the database is easy really, as all we need do is supply a name to be included in the

connection string.

This is what we see in my Management Studio environment - 'Object Explorer' :-

==================================================

Once we have created, by code, a new DB we will be able to attach it, and hence view it, in the MS IDE.

[ .. this attachment may work seemingly automatically when we refresh the Tables in the IDE .. ]

Lets make up a suitable name, lets call it "StockCodeFirst_L2S".

Lets look at the current code for defining the connection string to be used - check below :-

[ .. line 57 needs changing, as well as 62 .. ]

==================================================================================================

Lets see how we can easily adapt this above code for our new purposes, that of making a new DB :-

[ .. line 48, 56, and 62 are those to check out in particular .. ]

======================================================================================================

When we use the new static method for providing a connection string we need to supply parameters

for both the name of the Database as well as the file path where the .MDF will reside (be stored).

Lets now see how this is called from code, and from where :-

=============================================================================================================

In the initialising method seem above, lines 46 and 47 employ the connection string STATIC method.

We can then use 'ourConnection' later in the code sequence.

Below we see the most important place of its use - line 52 is where we use the connection string in

order to instantiate a DataContext object from our sub-classed DC class.

*** CARE *** we need to be careful in our coding above, as there is a situation which can occur during

development (it just happened to me) in which we do not have an MDF file in the folder where it once

was. So we need to check for this occurrence.

The problem I talk of only happens on line 49, when we try to use the string supplied.

So here is some code I adapted to solve my immediate problem - seems to be okay :-

============================================================================================================

You ought to try some of this file, folder and connection string stuff for yourself.

Its a matter of getting confident and gaining some skills and experience.

PHH - 29th. November 2016.


Defining our 'DataContext' sub-class

Defining our 'DataContext' sub-class

Defining our 'DataContext' sub-class

 Previous topic Next topic

Remember that the DataContext class of object is the crucial one for L2S to work.

A sub-classed DC object effectively sits between the Table class object and the SQL table.

It effectively completes the mapping.

So lets see what my simple three Table DC class looks like.

Although there appears to be quite a few lines, in fact there is not that much going on.

Below we see three properties declared and defined - check the details :-

=====================================================================================

*** The hidden code is just commented lines to aid my typing at the IDE.

PHH - 29th. November 2016.


Naming and defining the Tables

Naming and defining the Tables

Naming and defining the Tables

 Previous topic Next topic

I like to keep things simple when I can, so lets do that now - 'simple is best' !

Lines 38 and 39 show that we are to have a SQL Table named 'Invoice' as well as the .NET class

being named the same - 'Invoice'.

Check the other details shown below :-

======================================================================================================================================

In the above code we need to see that the all important Attributes are present and correct - these

are at lines 38, 41,42, and 43.

The attribute properties on line 41 are 'all important' as these will allows us to be able to insert and update

Table rows - this includes deleting rows.

Note that we could provide other version of Constructor, it all depends on what we need later. It will

do quite nicely as it is - an empty Constructor.

There is more on Attributes and their use in the subsequent sub-section - below this one.

PHH - 29th. November 2016.


Adding more Tables

Adding more Tables

Adding more Tables

 Previous topic Next topic

=====================================================================================================================================

====================================================================================================================================

PHH - 29th. November 2016.


Checking our Tables with MS

Checking our Tables with MS

Checking our Tables with MS

 Previous topic Next topic

Although using Management Studio is nothing to do with L2S and making a working test app,

it is a useful thing to know how to use - to support work with SQL in general.

Below we can see the new database called 'StockCodeFirst_L2S' with just two Tables present.

In the following image we see the Table structure for 'Product' as well as some test data rows which

have been added from our app code for populating the table. Check the details :-

========================================================================================================================

======================================================

=====================================================================================================================

PHH - 29th. November 2016.


using Attributes - don't rush this part

using Attributes - don't rush this part

using Attributes - don't rush this part

 Previous topic Next topic

Enter topic text here.


'Populating' Tables with Data

'Populating' Tables with Data

'Populating' Tables with Data

 Previous topic Next topic

Once we have an app solution which creates the empty Tables, we can then add the code

to populate these tables.

The code is quite easy to write and create.

Below is the first attempt I tried, and it worked - it did need tidying up later!

Here is what worked :-

===================================================================================================================

====================================================================================================================================

===============================================================================================================================

An alternative way to code the data "Update" process :

Since it would appear that we can't send a whole List of objects to be registered in the 'changes' or 'InsertOnUpdate'

system, we need to handle each Table rows or class object separately.

Here is another way to code it, if you prefer it this way - see below :-

====================================================================================================================================================================

And if you like guys, there is another alternative too - check below for this :-

======================================================================================================================================================================

Personally, I can't say that this is much difference in any of these, to my eyes.

Each seems to need us to take care with commas, semicolons and braces, curly or round.

Probably the last one is slightly better in my eyes.

PHH - 29th. November 2016.


Getting our 'Key' data correct / suitable

Getting our 'Key' data correct / suitable

Getting our 'Key' data correct / suitable

 Previous topic Next topic

When it comes to 'keys' - Primary and Foreign, we need to take some care.

The 'seeding' of values does not seem as easy or as possible as when we do our design in Management Studio.

Here below is what the L2S technology does with the Customer data population. Note the ID values start at '1' - one.

======================================================================================================================

This then means that for any other test data involving 'CustomerID' values, they must be in the same range.

Below is an early effort by me and values starting at 1001 are consequently no good, not suitable - or incorrect !

====================================================================================================================================

Looking at the above image I need to go into VS and change the code and hard wired values for populating

the invoice table.

==============================================================================================================

===============================================================================================================================

As I add test data for item lines within each invoice I will need to take care that my test data 'relates' correctly.

By this I mean Product IDs, Customer IDs and Invoice IDs.

Normally, an existing SQL database will force relational integrity, and make sure that Foreign key restraints

are applied correctly - as we add new data items.

Since I fully intend to go to EF6 (or 7) I am not going to bother to find out if and how I can improve on what I

am currently doing to make some test data - AND - test data by its nature often does not make a whole lot of

sense past listing and selecting. It all depends on what we wish to do with our test data - how far we wish to

'push' it.

Obviously, if we start with an empty set of Tables and enter data via input screens, then as the data is placed

into the Tables it will be far more correct than when we manually type it and make it up.

Foreign Keys :

One thing I am not as yet familiar with is how to set up a Foreign Key relationship / constraint in our DB.

From a few web searches it does not seem as obvious as the other stuff I present in these eNotes.

' Watch this space ! '

PHH - 29th. November 2016.


The Main test app code section

The Main test app code section

The Main test app code section

 Previous topic Next topic

Hey you guys, the code below may seem a bit strange to you in its current operation - BUT - there

is a real purpose to how it is at the moment.

Line 53 through 56 actually check to see if a database exists with the name details (connection) provided,

and if it does then it is deleted.

Line 59 makes sure that database (DB) is created afresh. Until we comment lines 54,55 then this will

happen each time we run this test app.

Yes, I know that it will sound odd deleting a whole DB and re-creating it, but we are actually still in the

development phase - we have still things to add to our DB and its Tables.

Normally, when SQL guys design and create DBs and Tables and the likes, they do their work in the MS IDE,

or something similar as a design tool.

Here (below in our app) we are doing our cycles of design and change in the .NET code itself. Hence

the need to drop the DB and create it afresh each time.

Since it does not take much time at all on modern PC systems, what is wrong with this approach, even

to the population of the Tables with test data ?

Check below for all the relevant details of this main portion (part) of the application :-

======================================================================================================================

Lines 63 through 65 are where we populate the Tables with test data, so we can expect there to be more lines

included soon as we add further Tables to our solution.

Also, when we eventually get what we are after in our DB, we will comment out the code lines to recreate the DB

and to add test data. At some point we will just create a new DB and leave the tables unfilled, ready for real

business use.

I will make another image capture of the code when I have completed the development.

At the moment I have just got things working after about an hours work on the app yesterday.

Yes, it does not take much time to set up a new app with a new database - great for .NET guys ;-0)

============================================================================================================

PHH - 29th. November 2016.


What happens at 'Runtime' - making development changes

What happens at 'Runtime' - making development changes

What happens at 'Runtime' - making development changes

 Previous topic Next topic

Well, in theory it is easy what happens at runtime ;-0)

During the development phase of any / many applications using L2S technology, and "Code First", we

have the new and growing database being dropped (deleted) and then being created again immediately

after the 'drop'.

The Tables are also created and populated as part of the app initialization process.

Well, that's if nothing goes wrong anywhere - AND - it is possible to have Management Studio and the

application itself get 'entangled', or get into some deadly embrace.

I have just discovered that my code for app initialization was defective once I lost the '.MDF' file from

disk. So I changed and improved the code to be as seen below :-

[ .. lines 52 through 61 are where I made most changes .. ]

============================================================================================================

The code above checks to see that the MDF data file is present on disk, and handles the case 'if not'.

It also checks to see if the DB exists before trying to delete it, and a couple more obvious similar sort of things.

After all, we can't populate a Table if it or its DB does not exist. As of now I don't check to see if the Table is

in existence if the DB is present - but I suppose a well designed code would do so ;-0)

The above code seems to be fine for development, and better than I had originally - although even that worked

well for a while.

It is NOT what works or doesn't work, it is how the code handles all runtime eventualities and issues, and that

includes the DB being 'locked' because of some Management Studio attachment. I had to clear this a few times

manually from within MS.

PHH - 29th. November 2016.


Development - Delete and Create a DB many times over

Development - Delete and Create a DB many times over

Development - Delete and Create a DB many times over

 Previous topic Next topic

It is normal to develop an SQL based app (using L2S technology) by starting simple and getting a runtime

success, and then gradually adding to the code which is run each time, cycle after development cycle.

This 'cycle' approach means that the DB is deleted (dropped) and created many, many times during the

development life-cycle.

This cycle style of development is probably not what we all did for the older ADO.NET way of making and

using SQL databases.

In fact while using the .NET coding approach, "Code First" it is know as, I tend to add one Table and its

mapping .NET Class, and then the code to populate it with test sample data, before going on to the next

Table.

When I worked with ADO.NET I would tend to design and create all the required Tables first, then worry

about test data. Quite different in my approach.

So you definitely need to find a way in which you don't get issues when you run your app and the initializer

removes and remakes the DB.

Oh! and placing the MDF file in a common or very accessible folder does help a LOT ! That is why I often

use the 'C:\Temp' folder.

Check below to see what I have, and when it was placed there :-

======================================================================================================================================

Look in the above image for the file fourth from the bottom - called ' StockCF_L2s.mdf '.

That is what I made today at just before 2.00 pm (November 30th. - St. Andrews's day - Scotland).

PHH - 29th. November 2016.


Some useful queries and results sets

Some useful queries and results sets

Some useful queries and results sets

 Previous topic Next topic

Okay folks, lets find out some useful information from our test data on Customers, Invoices,

and Products.

Lets find out the customers with at least one Invoice to their account. Some may have more.

The following query syntax (in X#) ignores customers with no recorded invoices - study thoroughly :-

==========================================================================================================================================================

======================================================

To make it easier to see any multiple invoices, we need to sort the results set something like that

seen below :-

======================================================================================================

Yes, notice that only Ben has more than one invoice at the moment - meaning with the test data

I hand coded into the app in the population methods.

Moving on .....................

Okay then, before we try to find out which products are used by each customer, let us first find

out which customers have empty accounts as far as invoices are concerned.

This next step should be easy enough as it has been done under section "Joining data from Multiple Tables".

However we get the following - check it out :-

=============================================================================================

Oh! we are trying to read nulls into variables which can't take them ;-0((

Lets re-visit the 'CustomerInvoice' class we are trying to use in our 'select' clause. Checkout below :-

==================================================================================

In the above image it is the property definition on lines 168 and 169 which needed changing, as

I had already taken care of 'nulls' for class type Customer - or should I say that 'string' types take

a 'null' anyhow !

Okay we no no errors now, and also some suitable results by the look of the above return data set.

Lets filter out the customers we do not require ................

Whoops ! - looks like Paul and Fabrice are "back to front" - must be my data population method !?

Oh! and Chris as well - will correct these now :-

==========================================================================================================================

PHH - 1st. December 2016.


Products for Customers

Products for Customers

Products for Customers

 Previous topic Next topic

PHH - 1st. December 2016.


Working code and script

Working code and script

Working code and script

 Previous topic Next topic

Defining and Naming the Table(s) :

Using Attributes - Don't rush this part :

What happens at Runtime :

Checking our Tables with Management Studio :

Adding some Data to our Tables (Persisting Test Data) :

Adding More Tables and Data :

PHH - 29th. November 2016.


LINQ to 'Entities' - "Entity SQL" - Entity 'Core'

LINQ to 'Entities' - "Entity SQL" - Entity 'Core'

LINQ to 'Entities' - "Entity SQL" - Entity 'Core'

 Previous topic Next topic

Okay you guys, first the good news - "there isn't any bad news" !

Once we can manage to create and write code for 'LINQ to Objects' then we have all the skills

required to apply to SQL and 'Entities'.

All we need to do before applying our LINQ query (and other) skills, is to make a suitable connection

to our database and find out how to use the connection to get back collections of data objects.

The whole bunch of stuff related to LINQ, like anonymous types, Lambda Expressions, Method syntax,

simple 'Query' syntax etc., etc. is all the same.

We may have to be a little more careful about the types of the results collections we have returned after

the query and how we then pass that through Methods to be 'Data Bound' in WPF forms. But the LINQ

stuff is all pretty much the same.

This is why I suggest you do a lot of work with LINQ to Objects and STATIC data methods, before you go

further.

Get good and do lots of test and trials with code written against LINQ to Objects.

=============================================================================

https://www.infoq.com/articles/multiple-databases

==================================================================================================

===========================================================================================================================================================

PHH - 18th. and 21st. October 2016.


History and Future !?

History and Future !?

 Previous topic Next topic

History and Future !?

 Previous topic Next topic

========================================================================================================================================================

===========================================================================================================================================================

===============================================================================================================================================================

===============================================================================================================================

PHH - 9th. December 2016.


No rush - EF6 is OK for the moment (now)

No rush - EF6 is OK for the moment (now)

 Previous topic Next topic

No rush - EF6 is OK for the moment (now)

 Previous topic Next topic

===========================================================

==============================================================================================================

==============================================================================================

=============================================================================================================================================================================================

===========================================================

=======================================================

=================================================================================================================

=======================================================================================

PHH - 9th. December 2016.


'Code First' - this seems to be the future

'Code First' - this seems to be the future

'Code First' - this seems to be the future

 Previous topic Next topic

http://sqlmag.com/entity-framework/5-reasons-why-entity-framework-can-be-your-best-friend

====================================================================================================

PHH - 9th. December 2016.


'walk through' - first working sample

'walk through' - first working sample

'walk through' - first working sample

 Previous topic Next topic

Okay guys, lets roll up our sleeves and get to work. We will make ourselves a new working SQL

database.

The small applet we will code in our X# syntax will use .NET code definitions to open up a connection

to an existing instance of a MS SQL Server on my PC and then create a new DB structure with just

one Table - Yes, one is enough to start with as we will by then have our foot in the door, as we say in the UK.

Once we have an applet to create a simple SQL database (DB) we can then turn our minds to seeding the

table, that is populating it with some suitable sample data.

Okay then, you know my style ! - lets start at the end by seeing what we will end up with when we achieve

the above. Here below is what I have created, shown from within Management Studio - check fully below :-

======================================================================================================================================

Notice in the above image that we have a single Table called 'Products' - ( catalog 'EF6_XS_Stock01' ).

You can see that it has just four columns, so the .NET class must have four fields - that is before we move

over to 'Entities' when a .NET class can have many Table related properties.

First things first, lets just work with one Table and four properties which from the 'Code First' (CF) approach

will give us four columns in our Table.

For the moment ignore the data values provided for population.

Lets study the X# code for the Product class in our .NET solution - check in detail below :-

=================================================================================================

For any of you guys out there that has attended my conference sessions on WPF and 'Data Binding', then

you ought to recognise that this .NET code is just exactly as it would be for a data binding applet using

WPF technology.

We have a class with private fields, and when these fields are linked to properties we notify changes to

these properties.

Note that we do not have extra code and lines with 'Attributes'.

Anything we included as attributes in the 'L2S' approach is now moved into the Configuration classes.

Here now is the configuration class required to go along with our basic Product class :-

=========================================================================================

So now we have both of these, how do we use business class and configuration class in our

code to create a new SQL database ?

Well, we need a 'Connection String' as well as a 'DbContext' sub-class that we define.

Remember the connection string will allow us to connect to the SQL Server and provide an MDF

file name, and the DbContext class acts as the 'bridge' in the mapping for 'O/RM' to take place.

First lets see the class and STATIC method for our connection string - its very similar to that used for 'L2S' :-

======================================================================================

You will need to change lines 46, 48, and 53 to suit your system and PC.

Now lest study the following details which are those in the required 'DbContext' class :-

[ .. notice how short this is .. ]

========================================================================================================

As well as two possible Constructors (and there are more possible) we simply have to specify which configuration

classes need to be added to the collection of configurations, as well as creating a property of the 'DbSet' of

that same business class, used for the configuration.

Yes, lines 110 and 114 go together, and if we have another Table or entity class then there will be another pair

of such lines. We will see this in the next sub-section.

Okay folks, lets see what we need to do to run our code when we execute the initializing code in our applet.

Study the following image carefully to see how it copes with all eventualities of data files and data bases,

existing or not - we need to take care of situations where early attempts to run the applet may fail, and fail

at different stages of file creation etc., etc..

=======================================================================================================================

We could comment out lines 57 and 62 in which case we would just get a DB structure created, and no data

showing up in the Table as rows.

But since this is tested 'working' code we are better just to see how the seeding and population is done.

We need two more classes with STATIC methods in order to deal with our Product data transfer, from code

to SQL database, at run / execution time.

First lets see the Population process :-

===========================================================================================================================================================

And now the seeding methods :-

==============================================================================

And looking back at where the seeding and population is done at initializing time, it is just

a single line to call upon the chained STATIC methods - first study this below :-

==============================================================

Yes, the 'SeedAllTables' method covers all Tables (or eventually Entities), as long as we

include each and every required population STATIC method.

Although I started simply with all new classes going into the WPFWindow1 PRG file, I have

now structured our solution explorer pane and moved the classes into suitably named smaller

PRG files. This will prove most helpful and useful as we develop the applet to be more 'Entity'

oriented.

Check the new structure :-

==============================================

Moving on ...........

Finally, a display of the returned results set - yes, finally we get to the LINQ part of this process.

Check below to see the seeded data read back with LINQ from the new SQL DB we have created :-

=================================================================

And so we now need to see the code to acquire the data from the SQL Table :-

===========================================================================================

As you can see we don't need line 40 for the code to work.

And here is all we need do to link (bind) the returned data to the data grid control on the WPF form :-

And last of all we need to see what needs to be added into the XAML script to make it work for us in

the way see above - below is our script :-

=========================================================================================================

All that I added was a better name for the control ( 'myDataGrids1' ) as well as attributes 'ItemsSource' and

'AutoGenerateColumns'.

Its as simple as that.

Lets move on and make things a bit more complex and realistic in the next section.

See you there .................

PHH - 13th December 2016.


'walk through' - improved working sample

'walk through' - improved working sample

'walk through' - improved working sample

 Previous topic Next topic

This may be an improved example, but as yet it is not really dealing with Entities.

We have two different Tables seeded with data - Products and Suppliers.

Once we have seen how to add the second table we will then look at changing the

Product table to have a property of type 'Supplier' - the we will be getting somewhere.

=============================================================

Okay folks, so we have a single Table for Products, and some seeded data. Great.

Lets add another table, that for 'Suppliers' - the related .NET class will be 'Supplier'.

Checkout the final result which includes the seeded supplier data :-

In order to fill the second data grid control we needed to add a second line of code for Suppliers

and this is shown below :-

==========================================================================================

Obviously we needed also a new query STATIC method - check the following :-

===========================================================================================

And the proof that the Table gets created in the SQL database, as well as populated :-

[ .. output from Management Studio .. ]

===============================================================================

It is important to see the structural results of our .NET code and the 'Code First' technology

of Entity Framework 6 - see the following details :-

===========================================================

Notice we have a Primary Key on the 'SupplierId' column.

Lets now spend a little time to see the flexibility of the object initializer syntax - all three data assignment

lines (68 - 70 are different :-

==========================================================================================================================================================================

Notice above that two of the data lines do NOT actually have an 'Id' assignment - that is because the data engine supplies

primary key values itself.

Now the changed code to upgrade the seeding and population - any new seed method needs to be added

into the 'SeedAllTables() method - this is easy to forget ;-0)

============================================================================

So what about the configuration for the new class and Table ? See below in detail :-

==========================================================================================

Once again we must remember to update or augment certain code 'parts', here it is the method

called 'OnModelCreating' method, as well as an extra Property being added :-

=====================================================================================================

Finally, and some would say importantly !? we need to study the 'Supplier' class definition itself :-

[ .. once again it is a standard WPF simple data binding type of business class .. ]

===================================================================================================

In the above code some code is hidden so that we can get a feel for the overall shape of the class.

As I said previously, nothing too different or too clever.

However, in the following (next) section we will start into real Entities.

See you there .................

PHH - 13th December 2016.


'walk through' - full 'Entities' sample, a start

'walk through' - full 'Entities' sample, a start

'walk through' - full 'Entities' sample, a start

 Previous topic Next topic

Okay guys, a nice morning here in Newport (Wales) and time for us to code our first Entity mapping.

Yes, I have a working applet suitable to discuss in detail with you.

The whole topic of making Entities and creating an Entity 'mapping', revolves around 'virtual' properties

being defined in our business classes, and these having a type of another business class object, or

a collection of such.

Here below, in our Product class we now have a virtual property of 'oSupp' which is of type 'Supplier'.

Check out the details in the following image :-

========================================================================================

Notice in the image above that the first column is displaying the 'oSupp' property ans since this is

of type 'Supplier' it shows the 'ToString' value, which I coded as being three value types concatenated.

Here is how we get the column display we see :-

==================================================================================================

And now we had better study what changes we have made to the Product class definition :-

=================================================================================

Note above that we have removed the field and property for 'Supplier' that we had in the last section

of the eNotes.

Instead of this we have a new 'virtual' property shown on line 276.

The consequence of these changes is that we need to seed our Product data in a slightly different way.

We need to find and provide an existing Supplier object (one in the 'Supplier' SQL table) and then assign

this to the new virtual property - check below for details :-

====================================================================================================================================

And to achieve what we see on line 62, 65, and 68, we need a new query STATIC method to return to us

the Supplier object for a given 'Id' stored within the SQL data table.

You need to check this code carefully, as we need to handle multiple returns and empty returns, even if

to us these seem unlikely or impossible :-

==============================================================================================================

At this moment, while we are discussing the seeding of data, and population, we need to also

consider the order in which we ask the seeding to take place.

In the following image we can see that the order of products the Suppliers does not work ! :-

==========================================================================================

Changing these around (lines 47 / 48) gives us success as seen in the next image :-

========================================================================================

So now we have stored (suitable) data we can retrieve it with our 'GetAll' methods seen below :-

======================================================================================================

Here is the one for Products and note we do not need to include line 40 (and we can spell correctly on line 41 :-

=======================================================================================

Here are the changes made :-

====================================================================================================

So although the Entity framework must be causing some sort of JOIN to happen, out LINQ

code is still as simple as used previously.

So both 'GetAll' methods are simple - and here are the results :-

Yes, we can also checkout the simple query code for Suppliers :-

==========================================================================================

Now then, it seems as though EF6 is doing a lot of complex 'stuff' for us. So what does the new

structure of the SQL database 'Products' table show us ?

Check below and notice that we have some 'FK' (Foreign Key) stuff showing up. Yet I did not

code anything to force this to happen - first check the DB structure :-

======================================================================================

And now we need to cross-check the code for the Configuration of 'Product' :-

================================================================================================

The above is just the same as it was before we introduced the 'Entity'.

We need to visually check the Suppliers table structure, to see that no FKs have

appear in it :-

===============================================================

Okay folks, we have had some good success, so lets move on.

In the next sub-section I will add more Entity mapping, for stuff like Orders, OrderLines,

Invoices and Customers.

See you then ...................

PHH - 13th December 2016.


'walk through' - full 'Entities' sample, much further

'walk through' - full 'Entities' sample, much further

'walk through' - full 'Entities' sample, much further

 Previous topic Next topic

PHH - 13th December 2016.


What is Seeding and Populating ?

What is Seeding and Populating ?

 Previous topic Next topic

What is Seeding and Populating ?

 Previous topic Next topic

Hi there guys, this is a very important subsection to read and think about / study.

If we are to do 'Code First' with Entity Framework 6 and beyond, then we must need to call

upon the skills of 'Seeding and Populating' data to persist in our newly created SQL Tables -

within the new database.

Quite often we need some initial test data to be able to develop new features, methods, and

classes, within our application. And this can't always be done by manually entering data at

'Views' or input screens.

Once we have a fully designed application then we may well wish to create a final (new) version

of our SQL database (DB) without any data at all - fresh, clean, and ready to go.

We need to be able to handle in X# code all of these possibilities / situations.

Much of the functionality is provided in convenient STATIC classes, as you will see soon (below).

Populating :

Adding a bunch of data rows to a Table in our SQL DB is populating it.

Seeding :

Placing bunches of data into a number of SQL tables after the DB is created (new), is

called 'Seeding' it. In the way that a farmer sows seeds into his freshly tilled soil in his fields.

When we have designed and created a DB structure in our .NET code, we then immediately need

to add test data so we can do many sorts of tests, using the features we have built into the

application solution.

So in my sample applet code you will see names including words like 'Seed' and 'Populate'.

Here is a look at one line in the initialising of a fully work sample applet for last year's Cologne

conference - 2016 that is :-

[ .. part of initialising code .. ]

==================================================================================================================

Note that lines 158 and 165 both do the same task - one for when the database exists, and one for

when it is not to be found on disk.

One line is usually all we see, as the full functionality required is built into the STATIC method code.

=====================================================================================

===============================================================================

=======================================================================================================================================

PHH - 15th. December 2016.


'Code First', Seeding, and Management Studio

'Code First', Seeding, and Management Studio

'Code First', Seeding, and Management Studio

 Previous topic Next topic

PHH - 16th. December 2016.


Seeding and Populating - basic approach

Seeding and Populating - basic approach

Seeding and Populating - basic approach

 Previous topic Next topic

When the Enity 'mapping' is simple then the data Seeding / Population is easy.

Think of 'Data Loading' as a term to cover Seeding and Populating.

However, when the mapping is more complex and we have business classes with properties

of type business object (BO) or collections of BOs, then the data 'loading' process can get a bit tricky,

to say the least.

What I mean by this, is that we will have Foreign Key constraints in place (made by EF) and these will

impose restrictions on what we can and can't do in the data loading process.

We may have to split up the seeding / loading task to get around this. I have a good example of this in

the next subsection.

Once we are up and running then we won't have such issues in the screen input 'Views' designed to handle

new BO's and their updating.

I spent most of yesterday fighting issues of this nature, until I got my head around things ;-0)

=======================================================================================================================================

===========================================================================================================================================================================

==============================================================================

============================================================================

PHH - 15th. December 2016.


LINQ queries to support data 'Seeding'

LINQ queries to support data 'Seeding'

LINQ queries to support data 'Seeding'

 Previous topic Next topic

When we start to do EF6 and the 'mapping' seriously (not just simple examples), it is easy to forget that

the results of the applets features, and its general performance, is still heavily based on LINQ and its

associated queries.

Let us take some time in this subsection to look at what LINQ queries we need, and how they (each) may be

parcelled (wrapped) up in a STATIC method.

First we need to study the LINQ syntax for returning a full list of Products, and another for a full list of Suppliers.

Checkout these details thoroughly :-

=======================================================================================================

Now then folks, when we get into doing more that just basic stuff, we need also to be able to return data for single

table classes, as well as Entities, and sometimes we will filter these as well.

Below we see how to find a single 'Supplier' with a specified 'ID' - see the following details :-

===============================================================================================================

Study the above code and see how we need to assure we get something returned, but also ONLY one object.

So 'GetAll...' methods return a strongly typed List, whereas 'GetSingle...' methods return on object of the specified type.

PHH - 15th. December 2016.


Seeding and Populating - issues and complexities

Seeding and Populating - issues and complexities

Seeding and Populating - issues and complexities

 Previous topic Next topic

Okay you guys, lets roll up our sleeves ;-0)

We need to be thinking straight and clearly too !

In the following image we see a list of our Entities displayed. These are 'Customer' entities with the property

values shown along the heading line. The final column is actually an Order item, itself being of a BO class.

Since the Customer object will generally be associated with multiple orders, we need to have the 'oOrderList'

property of type ' List<Order> '.

Checkout the image below thoroughly and carefully :-

=================================================================================================================================

===============================================================================================================================

==========================================================================================================================

==================================================================================

======================================================================================

PHH - 15th. December 2016.


LINQ queries to support complex data 'Seeding'

LINQ queries to support complex data 'Seeding'

LINQ queries to support complex data 'Seeding'

 Previous topic Next topic

Although our 'Seedings' and 'Population' may get more complex as we develop our applet, in fact the LINQ query

code probably does not generally get that much more complicated.

===============================================================================================

=======================================================================================================

=====================================================================================================================

========================================================================================================================

================================================================================================================

==================================================================================================================

PHH - 15th. December 2016.


Seeding data - two strategies, 'O' and 'R' !

Seeding data - two strategies, 'O' and 'R' !

 Previous topic Next topic

Seeding data - two strategies, 'O' and 'R' !

 Previous topic Next topic

Whichever way we look at it, when developing a 'Code First' (CF) application we need to have a period in which we have

some useful data in out SQL Tables, and this data we can use to develop and test further features and facilities within

our business solution.

I have found that I like to seed and populate very early on in my development phase, so that I can try out new business

related methods, and accessing my data in many more, and complex ways.

This can only be done since we can keep replacing the database by deleting the existing one and creating another.

So as we change and improve, and augment (build up) out Entities and their mapping, we add further suitable data for

our testing modules.

My advice after spending some time with EF6 and "Code First", is to do the seeding / population in an Entity way. I will

explain more of what I mean by this as the section of the eNotes unfurls, or unfolds before our eyes.

It is only way too easy to fall into the trap of trying to populate Tables, and not create and save Entities - this is VERY true

if we have come from using L2S (LINQ to SQL) where we do just about everything by the Tables.

Lets change our mindset and think 'ENTITY' !!!

Lets move on ..............

=========================================================================================

It would appear, after much thought, that my problems and issues that I had with trying to populate

my DB with data for Customers and Orders was down to using the wrong approach, or strategy. It all

makes sense now.

I was trying to add data in my .NET code as if I was populating single Table rows.

However, it now seems as though I should be doing the population via the 'Entities' that I defined.

So I was using an 'R' strategy when I should have been using an 'O' one instead. (Think 'ORM' )

Let me explain ................

Remember 'O' stands for 'object' and 'R' for relational.

Since using EF6 in .NET we are firmly on the side of the 'O', then this is how I should have approached

the issue of supplying the data. In an object way.

The more complex your Entity or Entities, then the more difficult it will be to populate data on a 'Tabled based' approach.

Doing it in a Table based way, you will have MANY more key constraint issues - you need to adopt the .NET code Entity approach.

When we do apply the 'Entities' approach we can forget the Keys altogether, we supply no primary of foreign key values at all.

The EF6 system seems to handle keys automatically for us.

The only time we need to bother with keys is when the Entity exists in the database, and hence we need a suitable ID value

to retrieve the object of the Entity. We shall see, its actually easy.

If we look at the following image we can see WPF controls with bound data which was seeded in the Entity way.

[ .. we have Customers with their Orders, and then Orders and OrderLines .. ]

========================================================================================================================

Until I really got a grip with Entity 'seeding' I simply did some hard coding in my initializing method.

Here below is small sample, I am adding three lines to orders for customers of ID 1 and 2 :-

==================================================================================

Lets now look at a small class that we have used previously (in the above code) :-

=====================================================

Moving on ...................

I have developed a whole class of STATIC methods for accessing the 'Stock' data within the database.

Below we see the method to add a Customer Order object for back-end storage :-

[ .. notice we use a subsequent method to retrieve the Customer object for a given identity .. ]

===========================================================================================================================================

We are going to add new data to the Orders table by changing a property within the Customer object, and saving the changes.

We are not going to concern ourselves with tables and keys.

In the above method we see that the 'OrderLine' lists from the start of the section, are supplied as an input parameter.

Lines 52 through 54 are the crucial ones.

We create a new Order, and then add this new Order object to the Customer property (of a collection of Orders), before

we save the changes. We are saving changes to Customer and not specifically the Order.

The new Order details are stored automatically as a consequence of saving changes to the Customer object.

By saving the changes we mean the retrieved Customer object is automatically being tracked for changes by the EF6 system,

and when we request 'SaveChanges' all will be sent to the SQL Server for us.

We really have nothing else to do to get the data and changes to persist. Easy ;-0))

Lets take some time to refresh ourselves with the structure of the 'OrderLine table as made for us during

the 'CodeFirst' process.

The following detail is from the Object Explorer pane in Management Studio - a very helpful software tool

when doing SQL database work of any sort :-

[ .. note in particular the keys made automatically for us, without our specific request .. ]

=====================================================================================

While using EF6 we have to get used to leaving a number of things to the Entity system itself.

It like good Team Work practice - just having the confidence to 'let go'. Trust in the system.

We will see much more on how to leave stuff to the EF6 system in future subsections.

For us to use the 'O' approach, that is writing code to create and change Entities and their property values,

we need some basic STATIC methods, like the couple shown below :-

[ .. we have already used the one to retrieve a Customer object from specifying the ID .. ]

===========================================================================================================

Okay then folks, now that we have cleared up some of the details about approaching the seeding of

data into our CF database, and that we need to 'think' Entity and not Table, we need to move on

to the next subsection where we can see how to build up a fuller, and more complete way of populating

all of our defined entities.

See you in the next sub-section ..............

PHH - 15th. December 2016 & 3rd. January 2017.


Creating multiple Entities - details to many Tables

Creating multiple Entities - details to many Tables

Creating multiple Entities - details to many Tables

 Previous topic Next topic

In our 'Stock' system we have a number of Entities, an important one being 'Customer'.

If we hard code a new Customer entity, with all its subsequent objects and collections, we can save

the entity back to the database, VERY easily indeed.

When we do such a 'save changes' operation in our code, we will have new data placed into up

to five different SQL tables. This is simply because of our business model and entity mapping through EF6.

The entity mapping effects tables Customer, Order, OrderLine, Product and Supplier.

If we are to use Entity Framework (6 and beyond) then we should as .NET coders, think of Entities 100% of the time.

It seems to me to be the RIGHT way to seed data into our database, by assigning values to properties in our Customer

entities and saving all changes we make by doing so.

Let us now study a STATIC method I have hard coded which does exactly as discussed above :-

[ .. we will make in our code a new Supplier and one new Product, as well as OrderLines for a new Order,

and all this is for a new Customer .. ]

============================================================================================================================================

Having used the above method in a trial / test run we then see the following retrieved data - check out Micky Mouse :-

======================================================================================

Yes, we seem to have added Micky, and a better WPF data binding situation shows this below :-

[ .. we now have a drop list for the Orders collection of the Customer entity .. ]

==================================================================================================

If we have saved all changes related to our new Entity then we should have the new supplier of 'Best Boxes',

so study the following details from the Management Studio IDE :-

================================================================================

We can also check the Customer table in a similar manner :-

===============================================================================

Now then, the Order details are less obvious to check out, but once we know the ID we can

then move on to check out the OrderLine details.

First the Order table :-

======================================================================

Yes, this shows us that Micky (identity '5' ) has an order of identity 33.

So now we can check out the lines of the order :-

======================================================================

Yes, above we can see that order number '33' has four lines to it, ID '131' through '134'.

Finally, we can see the new Product, ID value of '4' - study the following :-

===========================================================================

So in this example above we affected the stored details in FIVE separate tables, all from

one new entity - and a single short code line of "db:SaveChanges()", after we had added the new entity

to the 'Customers' public property of the DbContext object.

Easy ! - and also the right and correct way to add data for EF6 samples.

Moving on .......................

Fewer new nested Entities :

When making new orders for an existing customer we usually not need to create a new Supplier or Product.

Usually, stock systems have Suppliers and Products entered as a single and separate operation to making

new orders for customers.

In this case we need to query and find the correct oSupplier and oProduct objects before we make the OrderLines.

In fact oProduct is all we need to do this.

In line 61 of the far above code image, we see how to call back the correct products.

Lets now change and adapt our STATIC method code to add a new order to an existing Customer. We can try

Micky Mouse yet again ..................

[ .. alternative spelling 'Mickey Mouse' .. ]

============================================================

Okay then folks, lets use our WPF data binding to view the new order and its lines.

This is after I have run the changes STATIC method - as seen here :-

=========================================================================================================

Lets now see what new data we can retrieve, if any .................

Micky / Mickey is shown below - with his list of now existing orders :-

===================================================================================================================

Yes, it is easy guys, to spot the new order details, as today is New Year's day - see the date made value above.

The OrderId is '35'.

Now you can see the code I used to do this, it was the earlier method tidied and cleaned up.

Notice below that we have now lost the new Supplier and Product lines, we only find existing objects

for Customer and Product - lines 112, and 106.

=============================================================================================================================================================================

It is good to remind ourselves that yet again we have not had to worry about primary and foreign keys for new entities.

The only IDs we used were to find objects (entities) for already existing data entries.

So we used '5' for the customer ID, and 4 and 2 for the product IDs.

These existed and so we had to find them.

Now lets focus on the OrderLine items we created and saved - IDs 136 and 137 seen below :-

=========================================

Now we can use MS IDE to check these out - study carefully :-

======================================================================

Well, al the above details look okay, and what they should be after seeing the hard

coded details in my X# code above.

Quantities 3 and 1 are a helpful cross-check.

Before we leave this section, it should be said that seeding data through the Entities is by far the

best way to make test data when we are dealing with EF6 as well as CodeFirst.

Keep away from seeding Tables as such, and at all times 'Think Entities'. That is why we have

bothered to make the 'mapping' in our .NET classes.

Time to move on ............... see you in the next subsection.

PHH - 16th. December 2016 & January 1st. 2017.


Multiple new Entities - the easy way

Multiple new Entities - the easy way

Multiple new Entities - the easy way

 Previous topic Next topic

Okay then folks, we saw in the last subsection how we could easily make a new order for an

existing customer, and with existing products / suppliers.

We left a LOT for the Entity Framework system to do for us.

Lets now try to write a 'data seeding' static method which does quite a few customer orders at once,

using the existing Product / Supplier data.

Often we need plenty (lots) of test data, so we need an easy way to do this - make MANY orders, that is.

We need to try to vary the structure of each Order, in our case simply randomise the number of

order lines, as well as the chosen quantity and product identity.

Before we can start to randomise our seeding, in any way at all, we need to try out the random

facilities in .NET and how we are to use correct syntax in X#.

Over the years I have used Random facilities but more by good luck than good judgement - so be

warned, I am no expert.

Here are three ways to open / instantiate a Random object for thereafter generating random numbers :-

[ .. yes, I know that we could use only one object many times for different things - BUT - lets do

things in a more tidy manner .. ]

===================================================================

If order to keep my code tidy I will create and instantiate a separate Random object for each of the separate

types of random number I require - you know, one for customer ID, another for product ID, and so on and so forth.

Okay then folks, lets start with a chunk of hard coded detail that I used very early on - check below :-

========================================================================================================================

The above code was part of some lines within my Initializer code (method) which added a new couple

of Products to the existing bunch / list.

I have a feeling that we may be missing a couple more lines like that on 151 so don't just copy the code

and hope ;-0)

We will soon develop a much better way of doing the same thing.

Meanwhile look at what this type (or sort) of code gives us - including my double entry because of an error

when I run the code - check below :-

===========================================================================

Okay then guys, how do we use our existing Products (error included) to design a random way of making

and saving Orders with their OrderLines ?

*** CARE *** Due to me misunderstanding and misreading, the way to use 'Next' is slightly incorrect.

The second value to define a range for the random number selected is 'exclusive' whereas the first value is inclusive.

So all code involved in using 'Next' should have the second parameter increased by +1.

=================================================================================================================

Since we are only making and saving one new Order at a time we can use this data oriented STATIC method :-

[ .. this is not the way we would do many (lots) as there is a faster way .. ]

====================================================================================================================

Note line 116 where we (or should I say the EF system) saves the changes back to the back-end data source.

If we add many Orders we should not 'save' after each one, the performance is VERY poor if we do things that way.

More on this later.

Lets now look at the some of the new order data as seen in the IDE of Management Studio :-

[ .. note that I must have run the same code a few different times, check dates and values .. ]

=====================================================================

And for these new order we have even more new order line rows - see below :-

==================================================================

Okay, I will leave it to you guys to check the full details, and so convince yourself as to

the correctness of the rows and values etc..

Lets move on to see how to best add all the Entity data through suitable seeding methods.

The next subsection deals with randomisation as well as all Entity seeding and population.

We will also see in further sub-sections the suitable STATIC methods for Suppliers, Products,

Customers, and then Order/Ordelines.

See you in the next section ................

PHH - 1st. & 3rd. January 2017.


a whole approach to seeding with randomised test data

a whole approach to seeding with randomised test data

a whole approach to seeding with randomised test data

Previous topic Next topic

Okay then guys, here is my advice after trying out quite a few things on the data seeding and population

side of things.

Try to hard code as little as possible, but always code 'Entities'. Forget Tables in the SQL database and

think totally of your entities.

So think Customer, Order, Product, Supplier, etc., etc..

Do NOT bother with, or go near, identity values when they are for Primary and Foreign keys. Leave everything

to the Entity Framework system.

The ONLY time we need to use IDs is when the Entities already exist in the database. So to retrieve a Product

for example, use the 'ProductId' value and a LINQ query.

Also, we need to 'SaveChanges' but don't do any saving till all the new entities have been created.

At most do a 'SaveChanges()' at the end of the population of Suppliers, then another for Products and then

Customers and so on.

Remember that changes must be saved first, on entities that are required later in the 'seeding' process.

If we wish to create a bunch of Products then the Supplier details must be saved first.

You will quite quickly get the idea about this when you do some experimentation.

For my "Stock" system we need to do this :-

(all this can be rolled into one seeding method - which calls upon others.)

- add a bunch of Suppliers

- then add a bunch or two of Products based on the existing Suppliers

- add a couple of bunches of Customers with the collection property for orders set to an empty List<Order>.

- now run a method 'process' based on randomizers to generate 'orders & lines' for existing customers [ the orders

are based on existing products ]

Value details of above process :- Cust ID random, number of order lines random, quantity and product ID random too.

Possibly make a few thousand new orders.

I made 5005 orders with a total of just over 15 thousand 'OrderLines'.

This approach means all the key values will be correctly related - done by EF6.

Also we should not end up with any NULL relationships either - as I had previously with Products.

- try to save the changes in a way which aids performance - try a few ways out practically, yourself.

The following few sub-sections will show you what worked well for me, with the 'Stock' system.

Adapt the approach to suit your own application / database system.

Take time to read and study existing working systems, don't rush off and do your own thing before LEARNING !!!

Good Luck.

PHH - 1st. & 6th. January 2017.


Suppliers

Suppliers

Suppliers

 Previous topic Next topic

Lets get a couple of things straight - what I mean by 'Seeding' and what I mean by 'Population'.

In my eNotes I will use 'Seeding' to mean the process of placing a whole structure bunch of data

into a newly created database.

'Population' I will use to mean providing a the very detailed information for many entities to be placed

into the SQL database.

It is very common in web articles to see and hear folks talking of seeding and population as if they

are one and the same thing - which is some ways they are I suppose.

Anyway, together they achieve the goal of placing suitable data into our structure Tables. Ready for

testing and trialling.

So if I am to make a detailed static method called 'PopulateSuppliers' which simply provides a list of Suppliers,

as return from the method, we can then write a 'seeding' method to use this 'population' data.

Here is our Seeding method - simple as it is, note it is part of the class 'SeedTable', which under the

circumstances may be better called 'SeedEntities' !?

Check this out carefully :-

==================================================================================

Notice line 37 - its a regular 'gotcha' to miss out the call to save the changes ;-0) It will get you sometime

or another !

Now the 'Populate' method is similar to what we have seen earlier :-

================================================================================================================================================

The seeding of the Suppliers can be done on its own, in isolation, as it does not depend on

any other entity being in existence.

This is not always the case as well we will see for Product in the next subsection.

For the moment check out this Management Studio display of Suppliers seeded by the

above code :-

===================================================================================

Okay, looks good, time to move on ...............

See you in the next sub-section.

PHH - 2nd. & 3rd. January 2017.


Products

Products

Products

 Previous topic Next topic

Okay guys, having seen how Suppliers are seeded, we will see much the same thing done for Products.

However, each Product entity needs an existing Supplier object to be used. This is retrieved from the

back-end database.

Lets start with the short 'Seeding' method, check below :-

===============================================================================

Yes, we need the Population method to provide a list of suitable Product objects.

Here are the full details - note lines similar to 76 which retrieves from the DB a single Supplier object.

This is then assigned to the new Product object - property 'oSupp' - check the details below :-

========================================================================================================================================

I am aware that in a real life situation we would keep the prices of product outside of the Product entity / table

and place it in a 'Prices' (or similar) entity where dates of price updates can be tracked etc..

In a real 'Stock system we would wish to be able to know the cost of an item at any one date and time, going back

to when the product was first entered into the stock system.

What we have above will do nicely for our developing test 'Stock' system.

Lets now take a look at what this seeding / population achieves in out SQL database :-

===========================================================================

Okay, this looks fine, now we need move on to the Customer entity and how a bunch

of suitable Customers are specified and persisted.

Lets move on.

See you in the next subsection ................

PHH - 2nd. & 3rd.January 2017.


Customers

Customers

Customers

 Previous topic Next topic

For the Customer entities we will apply a different strategy.

We will create the Customer objects (before saving changes) and then to the property entitled 'oOrderList' we

will assign an empty list of Orders (a collection).

Then at a later stage we will create new Orders and add then into this collection property in a separate seeding

method.

Lets start with the Customers seeding method :-

=================================================================================

And now the details for all of the properties, including the empty order list - study this carefully :-

================================================================================================================================

We can also do a sample Customer table display, even though the Entities themselves are

yet to be completed - check below :-

=======================================================================

Yes, just as we might expect.

Time to move on ............................

See you in the next, and more complex, subsection.

PHH - 2nd. & 3rd. January 2017.


Orders and OrderLines - Auto methods

Orders and OrderLines - Auto methods

Orders and OrderLines - Auto methods

Previous topic Next topic

Okay guys, this is where it gets more interesting - not difficult, just 'interesting'.

To add orders to the Stock system we have to make a few OrderLine entities (or objects)

and then from this list of OrderLines we create an Order.

This Order is then added to the existing list of Orders in a randomly selected Customer entity.

AND - don't forget the 'gotcha', we have to save the changes, somewhere.

*** BIG POINT TO LEARN *** We can save changes in a whole bunch and not just singly.

It is more performance friendly to do a bunch at a time, as we will see.

Here now is the 'super' method to cause all the seeding to take place :-

[ .. each 'Seed' method saves changes before returning to the overall method .. ]

=======================================================================================

Notice in the code above that lines 62 and 63 will cause '213' order entities to be added and stored.

After I got this to work I used a much larger number, like 5005.

And here is the seeding method :-

================================================================================================

And here now the method to handle the population process :-

[ .. note this is basically my first attempt, and I have a much better solution to show later .. ]

=======================================================================================================================

Wow ! - we do need to talk about this a small section at a time. And remember I do have a better approach to show you later.

First notice that the method is designed to add any specified number of Orders. This number comes

in as an input parameter called 'nTot'.

Also, we will use randomly selected existing Customers, and Products (the Suppliers are within the Product entities),

in order to make up the new Orders and assign them to the customer entity.

We can discuss the details more fully about randomisation in a later subsection.

The Outer For / Next Loop :

One loop is per customer.

For each customer we get a random value for the number of lines within the Order.

We zero the running cash value total.

The inner loop creates the bunch of OrderLine objects to be added to the new Order. (More on

this later.)

Line 189 is not necessary as EF6 will do this for us - sorry my inexperience!

After a few other small things on the order detail, we add the new Order to the customer's order list.

Line 196 makes the changes persist in the DB.

The Inner For / Next Loop :

One loop is per Order.

The inner loop handles the handful of 'OrderLine' objects required for the new Order.

Random values are found for quantity and product ID, and then the Product object found by LINQ querying,

Then the 'OrderLine object is instantiated and properties assigned values.

The running total is added to.

And that is it ;-0)

We can make this a lot cleaner, tidier, and easy to read - but essentially it will be the same thing.

Look later at the improved approach using one Random number "Server" and two servers each for

Order and OrderLine.

Lets move on .................

PHH - 2nd. & 6th. January 2017.


App initialisation

App initialisation

App initialisation

 Previous topic Next topic

While we are developing our EF6 application, and still making changes to our Entities and their mapping to

the Code First database (and it Tables), we need to delete and create the database most times we start our application.

If not every time then many times, and probably frequently as well.

So we need a simple way of creating the DB and populating it with data, or simply keeping what we did previously, and

using what we had when the application last ran.

Here is how I start me current test version of the 'Stock' application :-

================================================================================================

Notice that in lines 36 and 37 we have the two 'opposite' initialisation calls.

Here below is a sample of a version I had recently - it is for the Initialize method, the one that creates the DB :-

[ .. study the full details of the following code .. ]

===============================================================================================================================

If the DB is eventually made (or created) then the data seeding process is started.

Since here we are not really studying EF6 but rather LINQ, then we will not go any deeper into the

possible settings of the DbContext class for setting initializer etc..

For now, check below to see how line 94 does this - starts the 'seeding' that is :-

===========================================================================================================

So we see from above that it is the 'AutoSeedAllEntities' that we need to study - see below :-

[ .. notice that it is in class 'SeedTable' .. ]

===========================================================================================

The STATIC method calls upon all the separate 'Seed' methods (or modules), one by one, and

the order does matter - which comes first, or before another one really does matter.

Notice that on line 174 we have a call to the third version of my 'AutoSeedOrders' static method.

5005 orders will be created and stored.

Enough for now, time to move ahead ...............

See you in the next subsection.

PHH - 2nd. January 2017.

Addendum :

We had better see what the 'Keep' version of my initializer looks like.

Check in the image shown below and note the section where I do my testing and trialling - new LINQ methods and the likes :-

=================================================================================================================================

The section between lines 59 - 64 can become quite large and filled with commented old tests etc., etc..

PHH - 6th. January 2017.


Support methods - LINQ

Support methods - LINQ

Support methods - LINQ

Previous topic Next topic

In order to carry out many basic data related functions we need some what I call 'Support' methods.

These are static methods which can be called from anywhere in the application.

They each perform some basic task relating to data stored in out DB and its Tables.

Here are a couple of such useful methods. In order to randomly seed a bunch of Orders

we need to know what the maximum values currently are for CustomerId, ProductId, and SupplierId.

Check these out :-

======================================================================================

We will use the top two of these shown above for seeding our DB initially.

Now some more VERY important STATIC methods - meaning they are used frequently, and throughout

the whole business application :-

=============================================================================================================

For example, from a single existing 'CustomerId' value we can retrieve the Customer object.

And here is another commonly used and helpful method - it gets all the existing Orders :-

==============================================================================================

You can imagine that once the DB is in use we are more likely to wish to retrieve a bunch of Orders

created in a date range.

I will leave it to you to code this modified requirement ;-0)

Lets now move on a pace or two ..........

PHH - 2nd. January 2017.


Working Results of "Auto-Seed"

Working Results of "Auto-Seed"

Working Results of "Auto-Seed"

 Previous topic Next topic

====================================================================

=======================================================================

=====================================================================================================================

==========================================================================================================================

===========================================================================================================

===============================================================================================================================

==================================================================================================================

PHH - 2nd. January 2017.


A better 'slice' of Randomness !?

A better 'slice' of Randomness !?

 Previous topic Next topic

A better 'slice' of Randomness !?

 Previous topic Next topic

Be careful when using Random objects.

I thought I had solved my simple requirements for random number generators in my 'Stock' code.

However, I found by pure chance that I seemed to get higher numbers of order lines in orders for

customers with higher identity values. Weird I thought.

After some extensive testing, and quite some test spent on trials and testing runs, I found a simple

solution to my issue, yes, by calling a random number twice in a row - throwing away the first

supplied value.

Check this out below :-

[ .. line 195 is the second call for a random number, after that on line 194 .. ]

=====================================================================================================================

PHH - 3rd. January 2017.


A full and new approach - 'Stock' database random creation

A full and new approach - 'Stock' database random creation

A full and new approach - 'Stock' database random creation

 Previous topic Next topic

Okay then guys, lets tidy up our code - both for the generation of random values as well as the Order

creation STATIC method itself.

By planning ahead in our design process we can generate some much nicer and easier to maintain code.

Seeding the data for Customer, Product, and Supplier, does not entail any randomisation process. The

details are just hard wired into the 'Population' static methods.

However, creating a whole bunch of Orders does require a random approach, because of the sheer numbers

of entities needed.

The process of randomly generating 'Order' and 'OrderLine' entities allows me to demonstrate this randomisation,

see below:-

[ .. the STATIC calls to 'RandomStockValues.Next_XYZ()' provide suitable range values .. ]

=======================================================================================================================

From studying the above image code we can see that all the Random 'work' is done by my STATIC class

'RandomStockValues' and its methods.

However, it has cleaned up the code considerably (a lot) and the above code is almost readable, even understandable ;-0)

So it should be easy to maintain it.

Line 235 is a call to the STATIC method which allows us to pass in a 'DbContext' class so that the back-end

database can be queried.

>> We must not do this before the Customer table has been populated <<

The number of existing customers and product is a 'live' concern and needs to be found before the new random Order

process gets under way. But after Customers and Products (and therefore Suppliers) have been populated.

Let us now view the new static Class I have defined, and its supporting methods.

We will discuss what role the Constructor plays later on.

For now checkout the properties and the 'Next' methods :-

=====================================================================================================================

The above code seems to work really well, and I like the look and feel of it.

It is good and easy to use in other places, classes and methods.

Here is the result of using this new randomising approach - note the IDs for Order and OrderLine :-

This was a nice success as well as a step or tow going forward.

Lets now move on, see you in the next subsection ......................

PHH - 4th. January 2017.


STATIC 'Servers' - Random, Order, OrderLine

STATIC 'Servers' - Random, Order, OrderLine

STATIC 'Servers' - Random, Order, OrderLine

 Previous topic Next topic

This sub-section on 'Servers' is a direct result of FORUM postings from Frank (Maraite).

He helped me get my head around what I am actually doing when I seed and populate my data Tables,

or more correctly all my Entities.

The STATIC Class your saw in the last subsection, entitled 'RandomStockValues' is actually a "Server"

for random numbers suitable for use with creating Order entities for my 'Stock' database system based

on Entity Framework 6 (EF6).

We should be able to tidy things up even further by writing / creating a server for providing a random Order

object, as well as one for providing an 'OrderLine' object.

The term "Server" is used simply because the class is 'providing' a data service to our code.

Lets look at our first new STATIC method 'server', it provides an OrderLine object created from randomly chosen

property values. The values are restricted in their range by the server for 'Stock' random numbers.

Study this carefully :-

=============================================================================================================

Above, we need to provide an active 'DbContext' object so that we can retrieve the single product object using

the LINQ base static method on line 38.

And now we need to look at the other new 'server' which provides an Order, based on randomly chosen values.

Obviously, the Order needs a bunch of OrderLine objects and so it calls on the above server a few times.

Check this out thoroughly :-

===================================================================================

I think you will agree, the above code looks a lot cleaner and easy to maintain. As well

as a lot easier to understand what is being done, or described in code.

SO then folks, now that we have our two new servers, lets see how the original 'AutoPopulate' method

has changed, and how much cleaner and clearer this looks too :-

===========================================================================================================

Yep! we can read this as "for a large number of times, select a random customer, then find a new Order based

on suitable random numerical choices, and save this into the customer's order list. When all is done and finished,

save all the changes back to the database.

I think you will agree that this is much easier to read and understand - AND - it still works correctly, as indee

the first version of the method did.

Ways to improve this - check that a Product can't be duplicated, i.e. only one OrderLine for a specific product ID.

Time to move on ................

See you in the next subsection.

PHH - 5th. January 2017.


Improving the 'Server' for OrderLine

Improving the 'Server' for OrderLine

Improving the 'Server' for OrderLine

 Previous topic Next topic

Creating business objects by automation and using a random values 'server' is great in many respects,

but it does have a few draw-backs.

One we have lived with so far in our Stock automated data seeding is the fact that the way we have

coded things means that we can have multiple order lines for the same product.

It is not likely that in reality we would have an order made with more than one line of the order for the same

product identity.

We will now try to make some code changes, and adjustments, to prevent this from happening in our

randomised system.

Lets take this one step at a time.

First lets adjust our existing 'LOOP' code to only include unique product IDs. Check the following :-

==============================================================================

In the above code, as we select products we check the ID against a gradual growing list of IDs.

If the freshly selected Product is already in the list then we just miss out on its inclusion in the list.

Hence the final list of OrderLines will be shorter than the targeted length of 'nL'. We will have fewer

items in our list. We can put this right later, first lets look at the runtime results of what we have

so far done to our code :-

=========================================================================================================

The immediately obvious difference is that the overall number of OrderLines has dropped from over 17,000 to

just over 13,000. So quite a few duplicates have been excluded. Which is good.

Before we go much further with improving our code :

Oh! - should have said ............

Because we only had a large handful of Product entities seeded to the SQL database, we need to add a few more,

the following makes the total eleven.

This means that if we are hoping for a MAX value for the group of OrderLines being 5, then we won't have much

thrashing about at run time - which can happens as a random choice tries to select one of only a few un-picked lines.

Here below are the extra four lines or products I added :-

============================================================================================================================================

And here is how the MS IDE looks after a suitable query :-

==========================================================================

Now we can continue with our selection code improvements.

Here shown below is an image where we select the correct number of OrderLines, and

also reject any multiple selections of product.

We have had to change the type of loop from a FOR / NEXT to a DO WHILE.

If you look below at the total number of OrderLines we now have over 15, from just over 13 thousand,

so things look to be working fine.

If you wonder why we are not at just over 17 thousand it is because I also reduced the MAX value from 6 to 5.

=====================================================================================================

Study all the details below, of output display as well as new code lines :-

=====================================================================================

Okay guys, we seem to have done our job, and improved the original code.

Time to move on ................

See you in the next sub-section.

PHH - 5th. January 2017.

Addendum :

When I originally made th 'Server' method for a new Order I did not get a blue response in the VS editor

and so I gave up and used Do While.

Since then I see that Repeat / Until does work but the colour change in the code made by the 'parser' is

not yet consistent with the for/next and do while / end do response.

Robert is on the case ;-0)

Here is the server with the new code added and tested :-

==========================================================================================

Hope that helps in some way.

PHH - 6th. January 2017.


Deeply nesting 'ComboBox' controls

Deeply nesting 'ComboBox' controls

Deeply nesting 'ComboBox' controls

Previous topic Next topic

Okay you guys, if we are to have "Business Entities" - sort of complex 'nested' business classes mapped to

SQL database Tables, then we are likely to need to show a nested form of our data in WPF form controls

like DataGrid and ListBox.

I thought it helpful to try out such a coding 'situation' with our Stock DB (database).

Lets look at a grid of Customer objects. Each customer has a list of Order items, and each of the Order

items has a list of OrderLine objects. So we are at least nesting list to two levels.

Check below to see this in action on my monitor here in my office :-

[ .. here I start with just one level of nesting - Orders within Customer .. ]

=======================================================================================================

So if we now increase this another level to make two levels of depth, we see the following nesting on my

monitor - Lines within an order for each customer :-

=====================================================================================================================

===================================================================================================================

===================================================================================================

=================================================================================================================================================

==============================================================================================================

=============================================================================================================================

===============================================================================

===========================================================================================

PHH - 20th. December 2016.


various LINQ queries to support data retrieval

various LINQ queries to support data retrieval

various LINQ queries to support data retrieval

 Previous topic Next topic

Okay guys, in many ways this is the 'fun' part of my research on LINQ and eNote writing.

We are now going to use the Test / Trial system for 'Stock' to create a whole bunch of STATIC methods

which return data from the back-end database called 'Stock'.

Or more correctly "EF6_XS_Stock01" - which is the full title I gave it in the 'Code First' lines I wrote now

some time ago - check below :-

==============================================================================================

Here below is the result of the Code First - shown in the Object Explorer of Management Studio :-

=============================================

And now how our EF6 / LINQ code appears in the Solution Explorer of Visual Studio 2015 :-

========================================

The folder is shown open, the one in which we will place all the STATIC methods we create to supply data

retrieved from the DB.

Lets look at the general form of a couple of these methods - checkout the Type of the returned objects :-

===============================================================================================================================

Above we have two Lists being returned and one 'ProdQtyCount' object (one of our business objects).

The Lists are 'typed' as 'int' for integer.

Because we are dealing a lot with collections, we will often return a List, or even an Array.

If we are unsure of the Type of the collection elements, because we have used an anonymous type in our LINQ, then

we can use 'Dynamic' as the type in our List definition / declaration - see below for a good example :-

========================================================================================================

It is often very convenient to use anonymous Types in out query syntax code, but that often means we are

a little unsure what to pass back as the return data set.

Lets have a look in detail at the section which was collapsed in the above image.

Notice that we are using three anonymous types in the first three queries :-

=================================================================================================

We will deal with what and how to return data in other sections later in the eNotes.

Look for "Passing collections" towards the end of the Appendix 'X'.

Some of my LINQ data methods do the following :-

Total sales value

Total sales value in a set period

Product sales between a date range - based on Orders

Products not used (time limits / date range ?)

Customers not ordering (date range ?)

Customers ordering between a date range

Customers ordering in the morning - or in the afternoon

Suppliers no product

Suppliers most products

Suppliers greatest sales value

All products comparative sales - collection and ordered

Customers no orders - at all

One product many customers. (Product used by .... )

Product items in single line orders - one order line.

And here is an image of some of the most basic / fundamental of my STATIC methods :-

=============================================================================================================

And then some other useful methods which return fewer objects, or even values :-

========================================================================================================================

The next one seems pretty fundamental to me - knowing the Orders that are associated with a single specified customer :-

==============================================================================================================================

Okay folks, lets move on .................

We will see and learn a lot more about data STATIC LINQ methods in the sub-sections from here.

PHH - 22nd. and 29th. December 2016.


Products used by a Customer

Products used by a Customer

Products used by a Customer

 Previous topic Next topic

*** Remember *** that both data binding and the general LINQ query syntax works much better

when we use Properties of objects, and not simple value types directly.

We will see this demonstrated towards the end of this small sub-section!

========================================================================

Its a simple enough request, wishing to know the products that a specific customer uses.

However, the solution shown below uses two STATIC link methods in order to return a data set.

We approach this by starting out with a collection of all of the Order entities for the specified

customer. Then we process the orders themselves.

From the orders for a customer we move to find the products within those orders, then simplify the

list of products to have only unique values in the results sets - by 'ProductId' values that is.

Line 219 uses the second LINQ retrieval method, and we will see that in detail a little later.

First of all see how the following image shows LINQ query code to process the Orders :-

========================================================================================================================

[ .. notice, no anonymous types used .. ]

For each Order we can generate a short list of OrderLines - these contain Product information.

Query one extracts the product information for each and every line in the longer list (or collection).

Yes, code above shows that this method unfortunately requires me to use a 'loop' - albeit a 'FOREACH' structure.

We can see an alternative coding later where we do not use any loops as such in our code.

First we need to see the following STATIC method to find the Customer order list - this is a standard method available

for use by other parts of the application solution :-

[ .. its pretty straightforward .. ]

=====================================================================================================================

Lets now go back to discussing the first (overall) method.

Lines 230 & 231 simply describe that the long list of product identity values are to be taken and from them

only unique values (one off) placed in the resulting short list, or collection of Product objects.

Lines 233 and 234 simply describe that we wish the product identity values to be stripped out of the Product

objects and placed in a list of integers.

Let us move on now to try and use the LINQ method to find us the Products used by customer number '5'.

===================================================================================================================

On line 225, if we just try the same assignment as we did previously, to the DataGrid control, then we see no

text detail on the WPF form when it loads and displays - see below :-

===========================================================================================================

However, you can count the blank rows to see that the collection 'number' is correct.

So to see the integer values lets try something simple at first - check the next image for details of what can

be done :-

============================================================================================================

And if for this number ' 1 ' customer we look at the DataGrid control, we see one less blank rows, and hence

items in the collection. See these details :-

======================================

Okay then, lets abandon the DataGrid and try something else ...........

Lets show this (the product Ids. list) by using a 'ListBox' control instead - see the following image :-

====================================

Yes, that looks more like it ;-0)

And now we need to see the basic XAML script used :-

================================================================================================

And also the calling code form our text section in the Initializing method :-

=========================================================================================

Okay then folks, success it would seem. We have done what we set out to do.

However, we need to realise that in one way it was easy for us, as we knew what object type we

were returning from the STATIC method - it was a List of integers, or " List<int> ".

In the other subsections of this section we will not be so lucky, and will need to think carefully about

what is returned from the LINQ methods.

Lets move on ......................

See you in the next subsection.

PHH - 22nd. & 28th. December 2016.


Products used by a Customer (directly)

Products used by a Customer (directly)

 Previous topic Next topic

Products used by a Customer (directly)

 Previous topic Next topic

We have more than one Entity within our business model being used for the 'Stock' database 'ORM', so

we have a choice of where we start to solve our problem.

Because in the 'Order' entity we have the 'CustomerId' (foreign key) value we can start from the Orders

end of things, and not Customers.

Here is the Order Table structure :-

================================================

And now we need to see the fields in the Order class, which become Properties of very similar name :-

===========================================================================

So in the section heading I use 'direct' to mean that we go directly to the orders / order lines stored, and filter

them by a specified Customer ID - we do not need to work from a specified Customer and then find their

Orders and so on.

In many ways this is a cleaner, clearer approach - BUT - it can only be used because the Order & OrderLine entities exist

in our business entity mappings already, as part of our general EF mapping structure.

Let us see what can be done to create a solution in code using Microsoft's query syntax, and use one 'query' within

another, in a way that keeps our code VERY readable, and gets the compiler and runtime systems to do all the

work of the real querying of the SQL data engine.

In the following code and LINQ query we are flattening the data structure - that is why we need a 'JOIN'.

Each Order has a bunch of OrderLines, in a one to many sort of structure. We use JOIN to give us an 'adapted'

one to one relationship. The left join (called INNER when used this way) must start with the 'one' which is the Orders collection.

For each Order we will get one or more composite rows, made from Order and OrderLine.

Check these details carefully (sorry Nick, but I like JOINs) :-

==================================================================================================================================================

If you have read and studied other parts of Appendix 'X' then the above code should make sense to you.

Note that we are having returned from the DB engine a collection of anonymous types which have one Property

called 'ProductId' which is itself of value type 'int'.

Using 'Dynamic' to type the List returned, means that the compiler ignores it and only at run time when the type is

know is it passed on and used.

Using 'Dynamic' get us around an immediate 'Type' problem / issue, but means we will have to deal with it somewhere

else in our solution code. There is more on this in the later section entitled "Passing collections".

Now we need to look at the real T-SQL statement made for us, and sent to the engine to have it generate the results

set returned to us - check this out :-

===========================================================================================================================

Well, my LINQ code is far easier to read and 'digest' (or understand) but it is basically pretty similar

in its structure.

Lets see the result displayed :-

===================

Since all we so far know about the Type of collection, and Type of collection item / element

returned is that it is 'Dynamic', lets do a trial to see what we have at runtime :-

First the collection :-

=================================================================================

And now the elements within the collection :-

[ .. remember that .NET has zero based arrays and lists .. ]

============================================================================================

So the first element has a value for its property of 1.

And then the next element property value, number '1' , is seen below :-

===========================================================================================

Yes, an anonymous type ( that's what the curly braces mean ), with one property called 'ProductId' and its

value is '2'.

So the last element has a value of 3, as seen in the next image - index of 2, for the third item / element :-

===============================================

And remember that Properties of objects are much better to deal with than basic value types that

are not Public Property values.

Many of our returned LINQ collection data sets will be probably data bound to WPF form controls,

so we need to think ahead to this, and present our retrieved data suitably.

Okay guys, lets move on and see some other examples of LINQ in use ........................

PHH - 22nd. & 26th. & 28th. December 2016.


Products not used by Customer

Products not used by Customer

Products not used by Customer

 Previous topic Next topic

Okay guys, here is a fun and interesting problem to solve.

In order to find the Products not being used by a given customer, we will find all of the Products and also

those being used by the customer, and then do some 'set algebra' to find the difference, so to speak.

Lets see how the code looks which defines the full LINQ query STATIC method.

Check this out :-

========================================================================================================

In the code shown above query1 finds all those product IDs which the customer currently uses, as well as

query2 finding all of the possible product IDs.

Line 279 does what looks like a simple task - BUT - it can sometimes be the only way we can solve similar

problems. I have used such 'set algebra' in the past to do some amazing and powerful things in my business

model solutions.

Keep this 'Except' approach in mind, as well as the other two of 'Union' and 'Intersect'. And note that these

operators can be used in a 'chain' like approach, using one after another after another .........

Here is the same code tidied and commented :-

===========================================================================================================================================

In the above code we are passing back a List of AT's (anonymous types). And we use the 'Dynamic' declaration

to allow compiler checking to be ignored for the list we are using. Only at runtime will the type be known.

We can change this to an array, as seen below, but we still have elements which are AT's. - Check below :-

============================================================================================================================================

As long as the set operation is done with sets of elements which are of the same object type, then stuff will work.

Here is an image of the above method in use :-

============================================================================================================================

And the display at runtime is as follows :-

======================================

And if we change Customer 1 to customer 4 we get the following :-

=========================================================================================================================================================

Yes, customer with identity '4' uses non of the four products.

Here is a way of using Management Studio to cross-check our findings.

Lets look at the Orders for customer number '4' :-

=====================================================================

There is only one order and it has an identity of '2'.

Lets see what we get for that from MS :-

======================================================================

Well folks, that explains things any possible order has associated with it a 'NULL' when it

comes to the Product item (object) in the OrderLine entity.

Lets move on .....................

If we wish to not use AT's then we need a suitable 'holding' class for the data values.

Here is a simple enough class :-

====================================================

Lets see if we can use it and pass back a strongly type list :-

=====================================================================================================================================================================

Line 297 and line 300 are places where we now use our new simple class.

Lines 289 and 304 is where we make a List of the 'ProductIdentity' objects.

Now I hear you say that we could have used 'int' instead, and had a List<int> passed back. Well, that

may be so but the method show above can be adapted and used for many other situations. I just wanted

to show you that it will even work for a single value type.

Usually we will have more than one property in our defined business class.

Note that if you wanted to have Data Binding in WPF forms, then it will be necessary to define the new

class so that the public properties handle change notification in the way I have shown earlier in these eNotes.

Lets move on and learn some more LINQ 'stuff' .............

See yo in the next subsection.

PHH - 26th. & 28th. & 30th. December 2016.


Best selling Product

Best selling Product

Best selling Product

 Previous topic Next topic

By 'Best Selling' we mean the product with the greatest sales 'value' - not the quantity.

We could of course write a method to find the product with the greatest quantity - lets do this later.

Before we can do anything about products and their sales (or not) we need to start with all the entities

called 'OrderLine's - each order line is associated with a Product object entity and also a quantity.

Also, we need to take care of an issue with my test data (its partly broken) in that we have a few 'nulls'

for Products.

Study the following image code, particularly lines 263 through 265 :-

==============================================================================================================================

As an outcome of query1 code we have an anonymous type (AT) class with two properties, a product ID and a quantity.

We now need to group this 'AT' collection, by the product identity.

Lines 268 through 272 above do some standard grouping - stuff seen previously in other sections within Appendix 'X'.

Query 3 is simply to order our results collection.

And by turning our results into an Array we can access the first element (X# is one based) so index 1 should be the first

element in the X# array - hopefully !

Here is the new small business class used above :-

==============================================

Lets see how we may use this STATIC method, and ones very similar which may return the full ordered list.

Check this out carefully :-

=====================================================================================================================================

And here is the displayed result and the calling code etc. :-

====================================================================================================================================================

You may be interested to see the actual full query script sent by LINQ / Entity to the SQL database engine :-

============================================================================================

And here is the same code copied and pasted into Management Studio :-

[ .. its not as readable and friendly as if we had written it, but it makes sense to those with T-SQL experience .. ]

====================================================================================

And here are the result rows of the query - so this is what will be sent back by the DB engine to the

.NET application of ours :-

===============================================

We can change our STATIC method to return the full product value list if we so choose.

I will leave that to you to do as some useful task based 'homework' !

Lets now move on ........................

See you in the next subsection.

PHH - 22nd. December 2016.


Supplier with greatest sales value

Supplier with greatest sales value

Supplier with greatest sales value

 Previous topic Next topic

Q. Which supplier provides the stock to the highest value of what is being sold ?

Not number of items, but total value of stock items shipped out.

============================================================================

We can solve some quite difficult problems in our business logic by simply using one relatively simple

query after another. Using the first query to feed into the second query code lines, and so on.

I call this 'cascading' querying.

This approach also means we do NOT try and make any of our own queries too complex, or complicated.

In this sub-section we are going to use FOUR queries !

Just for fun we will now look at the SQL query statement that the LINQ system produces at runtime

from the four of our queries - don't panic, the following image is to show you what we are keeping

well clear of :-

Oh! - yes, that looks daunting and difficult for all but experienced T-SQL guys.

However, the news is good, and all good ! We can do this in much simpler code step, and also

make our code MUCH more readable, and understandable.

Lets look at the success first of all. Check below to see which suppliers provide the greatest valued

product 'stock' - the value of goods sold :-

======================================

Yes, supplier with identity '2' is the source of by far the highest value of good shipped. In the ratio / proportion of 10 to 4

with the next highest.

100, 40, 20, and 2 is the 'rough' general ratio list seen above.

Lets see how my code is called, which does this data retrieval and calculation :-

=======================================================================================================================

Simple enough, but now we need to see the code which "does the business" as the UK guys would say.

Check through these details most carefully :-

======================================================================================================

Well, it certainly looks a lot more friendly than the earlier full SQL script.

Maybe we can fully understand it if we go through it a small section at a time.

Also, now that I look back at the code I developed an hour or two ago, I see that there are lines which

are not required for the solution.

This sort of redundancy often creeps into our solution as we mentally jostle (struggle) with the logical

concepts as well as data items.

The above can be simplified further as we have included a few properties which are unused, and unnecessary.

Now study this thoroughly :-

=======================================================================================================

Yes, the above code looks much simpler, almost trivial in fact !

To solve our problem all we really need is Supplier ID and the value of each line order in the full system,

then we group these by supplier, and sum the line values for each supplier.

We don't even need the line count values - order lines that is, the number of lines for that Supplier.

Lets now turn our attention to what data we pass out of the method - or should I say the Type of that data.

So far (above) we have passed out a Dynamic list, which just means the Type of the list elements is determined

at runtime.

Let us see how we can change things so as to pass out an Array, (a .NET System.Array type) , or indeed

an Array element :-

[ .. check out lines 320 onwards .. ]

=========================================================================================================

Before we have any discussion on what has been done, lets see the details as displayed at runtime :-

[ .. Oh! and remember that X# is one based for indexing .. ]

====================================

Okay, so we can make an Array from our 'query', but we still have elements which are anonymous types.

We could manipulate, and cast etc., etc. the single array element to make a Supplier object, but we will instead

look in more detail about passing back a collection.

Lets move on to study some other ways of passing back of data from the STATIC method.

Using Arrays :

Before we make any changes to the code used above, lets see what Type each array element is :-

==========================================================================================================

And also how the whole array looks when bound to a WPF data grid control :-

=====================================================================================================================

The above calling code produces the display below at runtime :-

====================================================================================================================================

Now then, we have a nice and useful display - BUT - we need to do something about the array elements

still being AT's (anonymous types).

It will be easier for us if we create (define) a new class to hold our item data. Check the following :-

======================================================================

Now we can use this new simple class in our LINQ query statements. Check below to see how it is done :-

==================================================================================================

Yes, this looks good, we now have an array of elements of type 'SuppValCount', and this should be available

to our intellisense system at other places in our code, where we use one or more of these objects.

I say the above, but can't prove it, as at the moment I am coding in X# in Visual Studio without intellisense

support. Yes, it is possible to do so but it would be much nicer to have it ;-0) Soon however !

Here is the code and the display to prove stuff works :-

=======================================================================================================================

Notice that the column headers in the DataGrid control are those of the properties of the new class 'SuppValCount'.

Lets look at lines 449 through 451 in more detail. Can we code things in a slightly different way ?

Checkout the following details to figure out what is going on :-

=============================================================================================

The code compiles and runs, BUT, at runtime we get the error thrown up which is shown above.

Yes, we can't use Constructors which need parameters, which also implies that we MUST have a

Constructor defined which requires no parameters - and 'empty' one ! By any other name.

In fact, if we don't have an empty Constructor then we can't use the initialising code.

So we now get this as a consequence of the previous message issue :-

Okay then, we will initialize in future, that is no problem to us.

However, if we now have a business class type of 'SuppValCount' we can create a strongly typed List to pass

back from the STATIC method.

Lets use List and not Array.

Here is the adapted / amended method :-

==============================================================================================================

And here is the calling code with runtime data display :-

===================================================================================================================

Yes, we could remove the 'self' input parameter, but I had it available to use for testing within the method - so I could

data bind and see any collection I needed to test and see.

So before we move on, what have we learned ?

Well, any defined business class we use in the 'select' LINQ clause MUST have and empty Constructor.

We have also learned that we can't pass in parameters to the selected class object, but can do initializing.

Time to move on to the next subsection ................

See you there.

PHH - 22nd. & 30th. December 2016.


Total Sales Value

Total Sales Value

Total Sales Value

 Previous topic Next topic

This is a much easier task, or problem to solve, than some of the previous ones.

We don't need to identify or deal with either Supplier or Product, just the values of the full list

or collection of order lines.

The value is a 'calculated field'.

We can actually do this in one go as shown below :-

======================================================================================================================================

The above works fine .........

However, it is often much better to split things up so that the code is both easier to read and also

easier to maintain.

The actual code being processed ends up in the same SQL query statement made by the LINQ technology,

and sent to the SQL database engine.

So lets do this task a step at a time, the first query makes the item list of values, and the second sums these values

to a total.

Now checkout these simplified details :-

=================================================================================================

Yes, in my eyes the above code is easier to maintain, and a bit easier to understand as well.

Remember that the 'M' on line 359 forces a numerical value of type 'Decimal'.

I will leave things to you to check that this grand total is actually the sum of the values for each of

the products separately - or even those shown below as the totals for all suppliers :-

======================================

This looks about right to me - visual estimate of just over eight thousand (grand).

Lets move on and learn some more LINQ 'stuff ' .....................

See you in the next section.

PHH - 22nd. & 29th. December 2016.


Customers ordering within a period

Customers ordering within a period

Customers ordering within a period

 Previous topic Next topic

==========================================================================================================================================================

==================================================================================================================================================

PHH - 5th. January 2017.


Customers with no Orders

Customers with no Orders

Customers with no Orders

 Previous topic Next topic

*** CARE ***

There is a difference between 'no orders' and orders which exist but have no (or 'null') order lines.

We will see how to deal with this situation later in this subsection.

=====================================================================

Okay you guys, you should know how to go about this by now ;-0)

"Lets answer the question which is exactly the 'opposite' to what we need, and then turn things

around at the last moment ! "

So, lets find all customers in one collection, and in another collection all those customers who have

one or more orders.

Then a bit of 'set algebra' magic and we find those customers without any orders !

Well that's the theory, lets now try it out.

Below is a simple image - BUT - it shows me success, I think.

Customer identity '6' is the only customer without orders - "Mr Donald Duck".

Check below for the calling code details and result :-

================================================================================================================================

And lets see if the direct querying with Management Studio agrees with this :-

====================================================================

Well, certainly no sign of identity '6' it would seem - notice that the list id ordered large to small on identity.

Lets now see what the query syntax looks like for the current LINQ method solution (STATIC method) :-

===================================================================================================

Yes, the above code is simple enough, and easy to understand - BUT - it will include existing orders

which have no real 'OrderLine' associations. Remember this for later.

And to see who customer identity '6' is check below :-

====================================================================

And sure enough if we make a direct query in Management Studio we get no results returned

for customer '6' - see below :-

===================================================================================

Well, that makes sense what we have seen so far - AND - line of code 492 is what turns

our answer 'around' - operating on the two sets for Customer.

Let us now improve lines 489 & 490 so that they find all of the customers with no order lines,

and that means they will have never received any products by shipment / deliver.

Yep! - sorry Nick, we need to do a spot of Entity 'JOINing' - Oh! I do like to JOIN !!!

Check this out folks :-

=========================================================================================================================================================================

Yes, the above results seem more in-line with the state of my test data.

It finds the two customers (3 & 4) that have null entries for OrderLines.

In a perfect world the previous (simpler) coding would work and be sufficient - BUT - data

does get 'damaged' or entered incorrectly for one reason or another.

So we are better to be safe than sorry, and code things in this more complex way.

However, we must not forget that the 'set algebra' is what makes this approach work.

Line 493 is 'King'.

Please note that the two 'sets' must be of the same Type of object (or thing).

We can compare and operate on 'Customer' objects or 'CustomerId's (integer values), but

both sets must be equivalent.

Also, an anonymous type of CustomerId properties is NOT the same as integer value of CustomerId.

We need to be careful on this when we use set algebra and set operators.

Get it right and things will go easily and well ;-0)

Now then folks, lets see what the new multiple query looks like when it is formed by the LINQ system

and sent via the EF6 framework to the SQL back-end engine.

Checkout these details :-

=========================================================================================================

The above system query is the result of the LINQ system combining our query, query1, and query2.

Don't worry about the complexity, but do notice the T-SQL reserved words EXCEPT and INNER JOIN.

Oh! and 'IS NOT NULL' also.

Time to move on ...................

See you in the next sub-section.

PHH - 28th. & 29th. December 2016.


'Set Algrebra' - operators in action

'Set Algrebra' - operators in action

'Set Algrebra' - operators in action

 Previous topic Next topic

Set operators are UNION, EXCEPT and INTERSECT.

They seem rather trivial in the grand scheme of things - BUT - can be easily and effectively used

to solve some otherwise difficult problems in our business applications.

We are going to find those Customers who have previously ordered product items 1,2,3, and 4.

Yes, which customers use all four products with these identities?

I happen to know that there is only one, but lets prove it, as well as finding out which customer that is.

First we need a static LINQ method to return all the customer IDs which use a single specified product.

Below is a suitable method and the '2' in the name simply refers to the fact that it is my second version,

or my second attempt at a suitable method solution.

Check these details :-

==============================================================================================================================================

When I applied this from my initialising 'calling' code I got the following results - check out all four of them :-

============================================================================================================================

And now Product identity '2' :-

========================================================================================================================================

And now Product identity '3' :-

=======================================================================================================================================

And now Product identity '4' :-

==========================================================================================================================================

[ .. only '5' is common to all four data displays .. ]

And just to check - '5', which does not exist in our data at the moment :-

=========================================================================================================================================

Here are the existing products with identities :-

[ .. just four of them .. ]

===========================================================================

And just for cross checking purposes, here are the customers with their identities :-

======================================================================

So we should be able to name the customer soon - lets see the new 'set algebra' operator based method :-

=============================================================================================================

In the above code we see that we first makes four collections - customers using the specified product.

We then in lines 521 through 523, cause the intersection of all four to be found.

This is then in 'query3' which can be effectively cast into a suitable list for returning from the method.

Lets now run this new STATIC method to see the calculated result :-

======================================================================================================================================================

Yes, the answer is a single element List collection which is bound to the WPF ListBox.

Note that it does not matter in which order the product IDs are supplied.

Oh! and so Micky Mouse is the customer using all four products.

But remember that the result set is actually a List or collection, its just that it has only one

element (item) within it.

Finally, lets do an experiment to see if we can see what is behind the 'query3' variable object.

Warning, this may surprise you :-

=======================================================================================

Yep! - we do not have the usual standard type SQL statement (T-SQL) script.

And the reason is simple - we already have our four customer collections as List objects 'in-memory'.

So the LINQ code never needs to access the database. So the reason we don't get SQL syntax here is

exactly the same as the reason we don't for L2O (LINQ to Objects).

Have a good think about this ;-0)

Lets now move on to see some more new and interesting 'stuff' .............

See you in the next section.

PHH - 29th. December 2016.


Extension Methods - Any, All, and SelectMany

Extension Methods - Any, All, and SelectMany

Extension Methods - Any, All, and SelectMany

 Previous topic Next topic

using 'SelectMany' in our LINQ querying :

The EM 'SelectMany' is very useful indeed, as it allows us the easily flatten an Entity, or a collection of Entities.

Let me explain.

In this first example, an business class Order object has a property which is a collection of 'OrderLine' objects,

from zero to many, items in the collection that is.

If we wish to make a collection (or list) of these 'OrderLine's we can use 'SelectMany'.

==================================================================================================================================

The above code on lines 167 through 169 means :-

From the Orders collection, choose the property called 'oLineList' and add all items into a single 'shallow' list.

It also means filter out only OrderList object (items) with a price within the range 220 to 260, and for only Order

items with an identity of less than 333.

By binding the resultant list to a simple 'DataGrid' we can visually check the results - check this display :-

=========================================================================================================================================================================

======================================================================================================================

====================================================================================================================================================================

*** CARE ***

We often wish to bind our returned data to a control on a WPF form.

However, we need to take care as how we do this, as the following easily happens if we do not

got our head around what we are trying to do - check this out :-

=================================================================================================

Obviously, the solution to the problem is to turn the resultant data into a List or other .NET object.

Here is what is required :-

==============================================================================

Line 173 does the necessary conversion.

For Any and All :

====================================================================================================================================

http://geekswithblogs.net/BlackRabbitCoder/archive/2011/04/21/c.net-little-wonders-any-and-all.aspx

=================================================================

==================================================================================================================================

==================================================

==================================================================================================================================

PHH- 29th. January 2017.


Items within the Collection - comparing one with another

Items within the Collection - comparing one with another

Items within the Collection - comparing one with another

 Previous topic Next topic

Very often we deal with SQL databases which have Tables with primary key identities and relationships.

And if done correctly these tables can't have duplicates 'as such'.

If designed correctly we can manage 'uniqueness' by careful use of the primary and foreign keys alone.

We should not need 'camparers'.

However, we do need to know how to create and define a 'comparer' for the times that we can't do the job

of comparing any other way.

=============================================================================

Most often when I am dealing with LINQ code, and also Entity Framework 6 (EF6), I am working with

collections of one item / element type. So it is common for me to have say a collection of 'Customer' objects.

For a similar reason I may often have a strongly typed list of Product objects, so each item in my collection

is a Product object.

My returned data sets from a query syntax sometimes is an item of AT (anonymous type) but the final collection

to be returned from my STATIC method will usually be a named Type.

Okay then guys, so we have a collection of similar and 'named' business class objects, so how do we determine

if one item (or element) is equal to another ?

Sometimes the answer to this question is simple enough, usually we would compare 'identities', or 'ID's.

However, there may be times when a Customer needs to be seen by other ways, like the Lastname and Postcode.

Or Lastname and Firstname and Telephone.

It seems pretty obvious to me that we need a way to specify just how we are to compare items from each of

our business classes. So for two objects to be 'equal' how do we define what we mean and / or require ?

Lets start by using the Product class from my 'Stock' database system. Check the fields shown below :-

===========================================================================

And for every field we have a public property with very similar names - we drop the underscore and change the

lower case leading letter (character) to an upper case one.

Okay then, lets try coding ourselves a 'ProductComparer' class.

Study the following details ....................

'Inherit' or 'Implements' ? :

Both seem to work as shown below, I need to ask Robert if there is a 'best' choice.

Oh! should have said that the C# code is not helpful on this as ' : ' is used for both cases.

First the 'inherit' approach :-

====================================================================================================

And now the 'implements' approach :-

=======================================================================================

Remember that in my simple tests both of the above approaches work okay.

Now then, lets look at a LINQ static method that I have adapted to use our new 'equality' comparer class :-

=========================================================================================================================

Yep! - still seems to work as it did before the code update.

Now lets look at what I have done to include the comparer - study in detail the following image :-

======================================================================================================================================

In the above code it is just line 241 which has been changed, and upgraded to a tighter form of comparison.

Here is the highlighted change :-

========================================================================================

Previous to this we had used ' :distinct() ' instead.

We can only do this because the items in the collection (list) are Product objects.

Lets move on a pace or two ...............

If we are to have a few classes for comparing, then it is best to make a specific file in the folder of

my SE pane for the 'Stock' solution.

Here is what I now have :-

=====================================

So I have moved any existing 'Comparers' into the new code file, and any future comparers will also be

placed in that file as well.

Lets now see the class that I have just created for our Customer class - check below :-

====================================================================================================

Notice line 107 and 112 uses the 'Lastname' property.

So when we apply this comparer we should see in the results set only Customer objects with unique 'Lastname' values.

Lets see below what the results set looks like, as well as the syntax to apply the comparer :-

===========================================================================================================================================================

Oh! - what happened to 'Jimmy' - we have a customer called Jimmy Williams.

Check this fact below, from the output of a query directly on the Customer table in the Management Studio IDE :-

=======================================================================

Yes, Jimmy exists, so our comparer using 'Lastname' did work as it should.

Now then, moving ahead, can we change the comparer code to allow Jimmy back into the list of

unique customers ?

Lets try to write a comparer class which deals with both .Lastname. and .Firstname'.

Check this out below :-

=======================================================================================================================================================================================

Yes, it looks like we have a working comparer which see Jimmy Williams as well as Florence Williams as

being 'unique'.

Lets see what the code looked like that we applied - study the following :-

=========================================================================================================

Lines 017 through 109 as well as 114 & 115 handle the pair of properties being 'tested', or checked.

It should now be more obvious as to how we adapt this class to handle other data oriented business classes.

Lets move on to the next subsection ..............

See you there.

PHH - 31st. December 2016.


which Extension Methods require a comparer ?

which Extension Methods require a comparer ?

 Previous topic Next topic

which Extension Methods require a comparer ?

 Previous topic Next topic

In order to get an idea of which Extension Methods for a List<T> object have overloads to accept

a comparer for equality, I have been through the long list and copied out the details most likely to

be of most use to us as coders.

Some of the following we have already seen in use in our small test samples.

We will however, write some test code to see more of these in use in further trial samples.

For the moment, cast your eyes over the following list - I have screen captured from Help Viewer 2.2

and pasted the details into a much smaller list of Extension methods :-

===================================================================================================

PHH - 31st. December 2016.


a General 'Comparer' for use will all Types

a General 'Comparer' for use will all Types

a General 'Comparer' for use will all Types

 Previous topic Next topic

work in progress >>>>>

=========================================================================================================

=========================================================================================================================

=======================================================================================================================================

PHH - 31st. December 2016.


multiple L2S 'mappings' in one application

multiple L2S 'mappings' in one application

multiple L2S 'mappings' in one application

 Previous topic Next topic

Okay guys lets move on to blow your minds (perhaps) in this sub-section and the next one.

I can excuse you for thinking that L2S and L2E are two separate things and can't be mixed up etc. !

But, we are just dealing with mappings between a SQL set of Tables in a Database (DB) and one or

more .NET class definitions.

So if I am saying we can mix the two technologies - have both types of mapping in one of our apps,

then it also must apply that we can have more than one L2S mapping within the same application.

From the point of view of complexity and performance, it probably makes more sense to mix L2S and

L2E, but we should also be able to mix different 'DataContext' sub-classes in one of our apps.

We need to remember that the whole point of a SQL Server is that it is disconnected from any one

single DB user / connection, and that it is designed to by multi-user, when oft 'multi' turns out to be

a VERY large number.

Let us remind ourselves that it is in the DB engine that the real 'work' is done, and not our application.

It is all very well separating ourselves from the reality of SQL but we should not lose sight of the fact

that the Server can do a LOT of clever work for us - so leave it to the DB engine. We must NOT try

and do too much in our .NET code!

Okay guys, lets do some coding 'experiments'.

Many 'DataContext' objects - one application :

As we may know by now, the 'DataContext' (DC) class object is the crucial one which sits between the .NET

classes of ours, and the data Tables in the relational SQL database.

The ORM is achieved by using a suitable DC object. 'Object Relational Mapping' is what is done by the DC.

However, we can define many more than one DC on exactly the same set of Tables, we just need to adjust our

.NET X# code to provide alternatives to our mappings.

And, we can use more than one DC in the same app, side by side, and apparently each at the same time.

This is all very clever, easy, and useful - so don't get alarmed ;-0)

Lets view the next image to start to see what I mean - lines 50 & 51 are those in particular :-

===========================================================================================================

In the above code take care to see the slight difference (actually a '2') in the lines 50 and 51.

We are actually instantiating two different L2S 'mappings' so we have two different 'DataContext' classes.

As well as the standard DC I developed earlier in these eNotes - see below :-

===========================================================================

we also now have a smaller light-weight version similar but definitely different.

Here is the second DC, based on two lighter weighted Table classes - check below :-

===========================================================================

================================================================================================================================================================

PHH - 2nd. December 2016.


mixing L2S and L2E in one app

mixing L2S and L2E in one app

mixing L2S and L2E in one app

 Previous topic Next topic

Quite possible (do test) - BUT - does it make any sense other than to see it can be done !?

PHH - 2nd. December 2016.


Lambda expression syntax

Lambda expression syntax

Lambda expression syntax

 Previous topic Next topic

Don't be afraid, even I can do this stuff ;-0)

https://msdn.microsoft.com/en-us/library/bb397947.aspx

================================================================================================================================

Lets have a look at what Lambda looks like in X# code.

*** Remember *** we have a parameter list followed by some method code. Often out Lambda parameter list is only a single item.

Below is a simple example to find the last names of all people (or persons) not living in London.

Check out in particular lines 285 through 287 - see code below :-

=====================================================================================================================================================

The way we read lines, 285, 286 and 287 is a bit like functional programming, and PowerShell for that matter.

We start (very often / usually) with an object of a collection type and pass this into the first method in the Method Syntax code.

The output from the first method then acts as input to the next, or subsequent method, and so on till the very end.

Yes, it different to a SQL query statement that we all are somewhat familiar with.

There again, simple 'Query' syntax is also a little different - all I can say is that with some effort and practice, we all

can get very effective with this type of code writing.

I use LINQ and some Lambda all the time now in my app solutions, and have done so since I 'saw the light' back in 2012.

*** NOTE *** Difference between C# and X# :

There is a slight difference in code syntax between C# and the samples we find on the web, and the X# syntax we need to use.

It is not big but it certainly matters.

Check this out :-

================================================================================

In C# we use "num >=" but in X# we use the code block syntax of "|num| ".

We also need to use curly braces in X# so the above for X# would be "( { |num| num % 2 == 0 } )".

Or, going back the other way we see :-

.Where({|p| p:Name:MiddleName != "middle ..."});

becomes :-

.Where( p => p.Name.MiddleName != "middle ...")

Get into the habit of including the extra pair of curly braces in our X# code.

Lets move on ..............

Here below is some working code which is using the Method syntax and Lambda expressions to do exactly

the same as the code shown commented in green - this is the alternative 'Query' syntax :-

=======================================================================================================================================================

So what does the 'p' actually stand for in the lines 292, 293, and 294 ?

Well, before we 'walk' our way through the code, lets look at a slightly different (or changed) version of

the very same code - check below in all details :-

================================================================================================================================================================

Notice in lines 312 - 315 shown above, that the 'p' has been replaced in all three lines, and that 'a', 'b', and 'c' have arbitrarily been

used in place of 'p'.

What is important to get right is that each of these then needs to be used (the same) throughout the line of code.

For yourselves try to spot all the occurrences of 'c' for example, in line 315.

Okay then folks, lets 'walk' our way through it.

We start with a collection of Person objects, that is what 'MyPersons' actually is, line 312.

In line 313, the 'Where' clause, the 'a' in the code block for the Lambda expression represents one whole item in this collection.

So 'a' is a Person object.

In the next line, 314, we are still dealing with Person objects and so 'b' is a Person item.

Likewise in line 315, 'c' represents an item in the collection provided to the Select clause. In our example this

is still a Person object, so 'c' represents a Person item in the collection.

However, the returned data set 'results4' is actually a collection of defined anonymous class items (or objects).

The anonymous type in line 315 is a class with four properties.

And if you really wish to know what type the system thinks 'results4' is the look at the image below :-

=================================================================================================================================================================

Wow !!! lets just keep it anonymous for the moment.

We will deal with moving data to collections of other know types in a later or different sub-section, as we

need to be able to pass collections back from methods to where these methods were called.

Quite often we need to do this for WPF and data binding purposes.

PHH - 18th. &21st. October 2016.


'Extension Methods' and 'Method' syntax

'Extension Methods' and 'Method' syntax

'Extension Methods' and 'Method' syntax

 Previous topic Next topic

https://msdn.microsoft.com/en-GB/library/bb383977.aspx

====================================================================================================================================

https://msdn.microsoft.com/en-us/library/bb397947.aspx

==============================================================================================================

===========================================================================================================

Okay then folks, lets use some XSharp syntax to make a working sample of both the 'Query' and 'Method' syntax

shown in the MSDN eNotes on this topic - the provided sample from MS is just below the text snippets seen above.

Check out lines 332 through 336 with the content of line 347 :-

============================================================================================================================

Yes, the console output shows that each of the two syntaxes does the same job for us.

We can of course structure the Method syntax in a similar way to the structure I have used for the 'Query syntax. It

does make it easier to read, particularly when we have a number of 'chained' methods.

How do you like this code structure ? :-

===================================================================================

Yes, I like it AND it still gives the correct answers ;-0)

While we are at it ! :

Hey guys, lets do something else while we have a collection of integers.

Lets take the original object, the array of integers, and simply apply an extension method to find ourselves

a few interesting values.

Check this out :-

====================================================================================================

==========================================================================================

PHH - 20th. October 2016.


Finding the Extension methods !?

Finding the Extension methods !?

 Previous topic Next topic

Finding the Extension methods !?

 Previous topic Next topic

Google 'System.Linq' namespace - a good place to start :-

https://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods(v=vs.110).aspx

==============================================

================================================

If we now use the intellisense facility in Visual Studio we get these available methods plus quite a

few more as well.

'Add' for instance, seen below, is not included in the 'Enumerable Methods' - these start at 'Aggregate'.

Lets see which EMs we can spot in the intellisense drop lists :-

===============================================================================

Notice that above the tooltip does not include 'IEnumerable' and yet it does below :-

=================================================================================================================================================

Also notice that this differential information is included in the little icons at the left of the text.

Compare the two icons in the following image :-

===============================================

===============================================================================

The little black downwards arrow is associated with the EMs we are discussing - see below for more :-

===========================================================================================================================================

And here are a few more - some very useful methods indeed :-

====================================================================================================================================================================================================

Here is a bunch more - the 'select' methods can't be done without ;-0) A real 'must have' :-

===========================================================================================================================================================

There are so many useful EMs, the list goes on and on ............

======================================================================

Good hunting, and do make plenty of time to carry out coding experiments, so you

can get a real good feel for what needs to be done to get the most from EMs.

Checkout my eNotes in the 'LINQ to Objects' section of Appendix 'X'. There are loads of

good examples to be seen.

https://msdn.microsoft.com/en-us/library/bb351562(v=vs.110).aspx

============================================================================================================

Lets move on ..............

PHH - 21st October 2016 & 3rd. March 2017.


A real life problem / example

A real life problem / example

A real life problem / example

 Previous topic Next topic

Remember that in X# we need to code the C# of :-

" c => ........ "

as

" { |c| ......... } "

and that includes the extra curly brace for those guys who like C# syntax ;-0))

===========================================================================================================

============================================================================================================================================================

====================================================================================================================================================================

=====================================================================================================================================

PHH - 18th. November 2016.


Arrays and lists of value types etc.

Arrays and lists of value types etc.

 Previous topic Next topic

Arrays and lists of value types etc.

 Previous topic Next topic

Well, guys, I suppose we have to do this sub-topic some justice, even though LINQ is seen at

its bets when used with collections of business objects.

There are a few things we need to know how to do, with lists of simple values types (and structures).

By this I mean arrays of numbers, and strings, and 'DateTime' values, and a few others too perhaps.

PHH - 19th. October 2016.


WPF and 'Data Binding' our collections

WPF and 'Data Binding' our collections

WPF and 'Data Binding' our collections

 Previous topic Next topic

PHH - 24th. October 2016.


So what are my problems - and yours likely to be ?

So what are my problems - and yours likely to be ?

 Previous topic Next topic

So what are my problems - and yours likely to be ?

 Previous topic Next topic

With some good examples to copy, or follow, we can all get quite good, and reasonably confident about the

LINQ code side of querying.

We will be able to get the correct data sets returned to solve our business solution problems. Usually these

are collections.

What I have struggled with over quite some time, and still do struggle with, is getting the right classes returned

in these results sets - for ease of use later.

I can define classes for the query results BUT then find it difficult to pass these around, or back, from methods

to other places within my code solution.

Anonymous types can be easy to use and pass around within a localised 'scope', but they become more of an

issue if you wish to pass then back from one method to another, back up the 'chain' so to speak.

We have all gotten used to coding by 'strong typing' and the code for anonymous types seems to me to conflict

in one way or another to how I usually code my 'stuff'.

My style of coding involves making a folder in the Solution Explorer pane for my LINQ queries, mostly those that

find and return data from the database engine - here is an image of what I have here :-

===========================================

And although the VS integration for X# at the moment does not give me the standard Expand / Collapse text code

features, I have manually compressed some code to show you what I have in this folder section - check below :-

=========================================================================================================================

And if I select one of these to study, we typically see something like the following :-

==========================================================================================================

Above we see a method to find the single Product identities for a specified customer.

The returned data is a list of 'dynamic' types, which basically means the type is undefined until the

time when the code is run and the data selected. Its like a 'place holder' and the compiler ignores it I suppose.

Since we know that the 'ProductId' is of type 'int' we can work out that 'query1' is actually a collection of anonymous

objects with a single property of ProductId and of value type 'int'.

The above example is one worth playing around with to get a feel for how to do things in different ways.

In the following section, and its sub-sections, we will explore such 'Data Query' methods to see what the various

options are for handling our return results data sets.

Oh! - and we must also remember that not all return data comes as a collection ;-0)

There are times we may have returned to us a DateTime, or a currency value of type Decimal. And there are

more examples of single data type values. Like 'number of days', etc., etc..

PHH - 24th. October 2016.


Passing collections - Returning collection objects

Passing collections - Returning collection objects

Passing collections - Returning collection objects

 Previous topic Next topic

Okay guys, remember I am coming back to LINQ and my eNotes after a long lay-off ;-0)

This means that in order to write some good eNotes for XSharp (X#) guys (and myself), I first have to return

to my original C# eNotes and see what I managed to do back then.

See, I do use my own notes for myself, and my coding - I always said I did!

Our first simple example shown below (in C# first) is where we make a typed list of a know collection item

type of objects, and return this list.

Here is the old example of mine, we will use 'Invoice' type items later in out test X# sample.

Check out these details thoroughly and fully - line 2182 in particular :-

==============================================================================================================================

Okay then folks, lets try this for ourselves with X# and 'Invoice' items.

================================================================================================

In the code above line 450 is responsible for including in our results set 'Invoice items - objects of type 'Invoice'.

This means that we can code line 452 to make a Typed List - yes, of 'Invoice' type objects.

As you can see the conversion in line 453 works just fine.

It won't be this easy when we use the 'Select' clause to create collection items of an anonymous type.

Going a step further ...............

And now just to prove we can return the list made from the results set converted to a List, see below :-

========================================================================================================

Yes, on line 531 we return the typed List, and the compiler is quite happy with this code.

How about us starting a WPF test application (project) and then trying to bind the returned collection to a suitable

control on the WPF form ?

For this exercise we will use items of type 'Person' in place of the above 'Invoice' example use.

Here below is a good start, even if it is not as colourful as my usual WPF efforts ;-0)

=====================================================================================================================================

Well, above the six data rows look to be the six returned data items, of type 'Person'.

Note that the first column is bound to a property which is itself an object, albeit a simple business object.

Name is a property of the Person class which is itself a 'Names' object, with properties of its own.

=====================================================

===========================================================

In my eNotes on WPF (and last Cologne conference) I have shown how to bind to a drop list, and even bind the

three Names properties to separate and individual columns in the DataGrid shown above.

For now we are doing enough as we should be concentrating our efforts on querying and dealing with returned

data sets in a suitable manner.

Oh! - we had better see how easy it is in the XAML script to show our results data - check below :-

============================================================================================================

Yes, just two line required, 9 and 10.

And to go 'hand-in-hand' with these two lines we need a suitable code line in our X# code too.

Check out line 32 shown in the image below :-

========================================================================================

Well now, that is all VERY easy I would say.

So what happens when we have some sort of a collection item filled with data items of an anonymous type ?

How do we go about passing such objects around our code structures ?

We need to be careful as we can cause ourselves a lot of unnecessary hassle - problems and issues ;-0((

PHH - 24th. October 2016.


The easy way out - creating results Classes

The easy way out - creating results Classes

The easy way out - creating results Classes

 Previous topic Next topic

Well then guys, the more I research this topic, and the more coding tests I do, the more I am convinced

that this 'easy way out' of things is by far the most sensible approach.

The issue is what 'Type' of collection element (item) do we create with our 'Select' clause in the LINQ

query.

Anonymous Types are all very well and easy to do 'on-the-fly' but then we have to handle the passing of such

results set around our code, and we hit issues of reusing the property values within the results set.

Lets take a clear example to see what I mean.

Below is a simple 'Class' I created to replace the anonymous type (AT) syntax in the 'Select' clause that I have

been using up until now :-

============================================================================================================

Yes, as simple as you like ;-0)

And here below is a commented bit of my previous working code which shows how I used to use ATs in my 'Select's :-

=====================================================================================================================

So what do we do now that we have a (as Nick Friend calls them) 'concrete' Class ?

Here is what works well at the moment :-

================================================================================

In the above code it is line 82 which has changed - in the detail of the 'select' clause.

Notice that at the moment we are using one of the Constructors that I defined within the 'concrete' Class.

I would prefer to use an alternative, something like those commented in the following image - check below :-

==============================================================================================================================

Lines 83 and 84 show the sort of thing I am after as a tighter syntax.

As it stands at the moment line 82 type of syntax allows us to mistakenly place the right values in the wrong place, or order.

We could easily get things wrong and place 'City' where the 'Email' should go. The compiler would not know better as both are strings.

I am working on it, even without Intellisense in Visual Studio.

Meanwhile, here is the proof that what we have added as 'concrete' Class coding, actually works okay :-

================================================================================================================================================================

*** CARE - Remember ***

If you need to do some serious data binding with WPF then your 'concrete' Class needs to be suitably coded

with facilities to track and notify property changes.

This exercise / procedure can add a lot of code creation to our otherwise simple class.

The good news is that when we come to 'LINQ to SQL' and in particular 'LINQ to Entity' we will usually have

already defined such Classes.

For now let just focus on getting our LINQ query returned data sets in a 'concrete' form which we can then easily

re-use in other parts of our solution code, in other program code structures, so that we can effectively move our

data around with as little fuss and issues as possible.

Lets move on a step or two ..................

Let us examine a useful approach which once again Robert VD Hulst has helped me with.

*** NOTE *** we will need to provide all four input parameters (or arguments) unless we provide other Constructor overloads.

===============================================================================================================================

=======================================================================================================================================

======================================================================================================================================

Here is a suggested 'Better' way to code our Constructor :

==============================================================================================

*** CARE *** we can still go wrong if we make human errors, the compiler is NOT "Magic" !!!

=======================================================================================================================

Compiler Improvements from Robert and the 'XSharp' Team :

Robert and his Development Team have made some changes to the current compiler (that is at the end

of October 2016) and we will see what these improvements are likely to be for us when we get the next

version of the X# compiler.

Here is what Robert posted a couple of hours ago :-

=======================================================================================================================================

In the above code it was the "Object Initializer" that we were particularly interested in, however, the "Collection

Initializer" is also a nice step forward.

Look out for further samples in these eNotes using the above syntax when the new compiler is available to us.

PHH - 25th. - 28th. October & November 2nd. 2016.


Dealing with Anonymous type collections

Dealing with Anonymous type collections

Dealing with Anonymous type collections

 Previous topic Next topic

Before we get straight into showing some successful ways to deal with anonymous types, and how

we may pass the results data to be displayed in a WPF form, lets see the sort of output we can easily

generate by the compiler, when we get things wrong - check below :-

=====================================================================================================================================================================

It is all too easy to generate error messages similar to the one shown above ;-0((

We need to know how to avoid such 'conversion' problems and issues.

Lets see how to launch a working example - see the changes below on line 31 :-

======================================================================

So then, what does the function look like that line 31 uses as the data set for 'binding' ?

Below is the simplest way to create a filtered results set with a limited set of data columns - CAREFULLY check the details :-

===========================================================================================================================================================

Well, it seems to work just fine.

We can pass back an array of Objects and still the DataGrid displays then as before.

Is there another, and similar, way to pass these back using a typed List ?

One way is to wrap the anonymous type items (objects) as something else, like 'Object'.

Here are some ideas to move us forward - first a bit of a trial with my code :-

=====================================================================================================================

Now it would appear (see image below) that this works, but we don't want to be enumerating is we can help it.

Here is the launch code and the WPF result :-

==========================================================================================

So if this works OK then what about wrapping up the AT in the query code, and not leaving it until we

have a results collection 'set'?

Here is the next step to wrapping the ATs and passing them on through our code :-

==================================================================================================================================================

Yes, its line 62 which we need to focus upon.

Since we can 'select' any meaningful object (item) that is available within the 'Query' code structure, we can

therefore cast the Anonymous Type (AT) to the basic 'thing' as an object, that is an item of the 'Object' type.

Lines 64 and 65 show how we can then convert the results set collection to a List of Objects.

*** NOTE *** It has taken me a long time to realise that I can do this. We are normally so concerned about

getting the LINQ syntax correct that we tend to forget the rest of the basic .NET and object stuff.

So I have done this in X# before ever doing it in C# - which is nice ;-0))

Now that we can pass back 'anonymous type' collection data, we can access it just about anywhere in our

solution / project code.

Lets move on ......................

Getting "Dynamic" !! - a suggestion from 'Robert van der Hulst' :

Well guys, as usual Robert has come good and given me an more than useful suggestion to help me out.

This below is my first go - BUT - there are some definite improvements following.

I did the next bit below, and then went away and slept on the problem, only to come good with a much better

way the very next morning.

Here is what I first did :-

================================================================================================================================================================

Yes, the WPF form shows that the code compiled and worked.

BUT, for my liking I would prefer not to have lines 90 through 93.

We should be trying to remove as many loops and enumerations as possible.

So with that in mind here is what my freshly 'slept' brain came up with :-

====================================================================================================================

And YES, line 65 is much neater than our previous rather clumsy coding.

So where does this leave us ?

We have managed to find the syntax return a data results set from both a Function and Method.

What we now need is to find the neatest and simplest syntax to access the property values of the collection elements,

outside of the Function / Method.

Well, the WPF form image of a the screen output, shows us that we can access the property values as far as displaying

via data binding is concerned, but how do we code to get access to these property values?

We need to try some test examples.

As usual Robert (van der Hulst) has provided me with some useful tips regarding the compiler and the required References.

If we try the following code in our solution it seems reasonable to expect it to run ! - check the details fully :-

==================================================================================================================

It appears (from Robert) that we are missing an entry in our References section.

Here is what I have when I get the error :-

===============================================

And here is what we have after adding the required entry :-

=====================================================

And so when we compile and run we get a 'runner' - yes, it works!

Now we can start to clean and tidy our code - check this out below :-

=====================================================================================================

Well, we can certainly get at (access) the properties of the collection elements / items.

Here is the output from the lines 35 and 38 :-

====================================================================================================================================

And now, most importantly, we wish to know what 'Type' of object are the collection elements.

Lets get and output the items 'Type' - check this out :-

=================================================================================================

Well, yes, that looks reasonable when we know how the returned collection was made in the method 'EightPlusSample()'.

Lets move on a pace or two ............

Let us try and use all of the returned data values, those of the properties of the list items, and display them in a simple fashion.

=====================================================================================================================

=========================================================================================================================

======================================================================================================

=================================================================================================================================

==================================================================================================================================

=====================================================================================================================================================================

====================================================================================================================

====================================================================================================================

PHH - 25th. & 26th. October 2016.


The 'Dynamic' Type

The 'Dynamic' Type

The 'Dynamic' Type

 Previous topic Next topic

Like it or loath it it can work for us in our code.

However, like a lot of things it should ONLY be used in the right place for the right reasons.

Lets first find out a few things about the 'Dynamic' type.

=============================================================

And here is some more useful information :-

======================================================================================================================================

In the following image we see an example of a data query in which I wished to have the results set as a

collection of anonymous type objects - see the commented line 104 below :-

============================================================================================================================================================

When I got error messages I instead resorted to making a special Class called 'CustomerInvoice', and this worked fine.

However, there are times when we may wish not to have to define a special Class, and so we can do as seen in the

next image, that is use the 'Dynamic' type as in my test code.

Here shown below is a case in which I have used a 'Dynamic' type successfully - and for the first time (almost) :-

[ .. the first real time anyhow .. ]

=========================================================================================================================

So above I can define my anonymous type as I first wanted to, and by declaring it as 'Dynamic' we get

around the compiler warnings / errors and the code compiles and run okay.

Here is how I action the method in my test app :-

========================================================================================

*** CARE - if you are wishing a object or a collection of objects to be in memory for a while, and used in many

different places, then you may have some difficulty with your code, because of its type.

I still think defining a specific Class type is a simple enough way around the problem - see below

for my current example solution :-

======================================================

Note that you may need to make your Class more comprehensive, depending what you wish to do with it.

Lets move on ....................

PHH - 26th. October & 1st. December 2016.


Robert's Stuff !!!

Robert's Stuff !!!

 Previous topic Next topic

Robert's Stuff !!!

 Previous topic Next topic

This is for me to use elsewhere in the these eNotes - in the X# Appendix :

USING System.Collections.Generic

USING System.Linq

USING STATIC System.Console

FUNCTION Start AS VOID

VAR oDev := GetDevelopers()

VAR oC := GetCountries()

VAR oAll := FROM D IN oDev ;

JOIN C IN oC ON D:Country EQUALS C:Name ;

ORDERBY D:LastName ;

SELECT CLASS {D:Name, D:Country, C:Region} // Anonymous class !

// The type of oAll is WhereSelectEnumerableIterator<<>f__AnonymousType0<Developer,Country>>

// We prefer the VAR keyword!

VAR oGreek := FROM Developer IN oDev ;

WHERE Developer:Country == "Greece" ;

ORDERBY Developer:LastName DESCENDING ;

SELECT Developer

// The type of oGreek is IOrderedEnumerable<Developer>

// We prefer the VAR keyword!

VAR oCount := FROM Developer IN oDev ;

GROUP Developer BY Developer:Country INTO NewGroup ;

ORDERBY NewGroup:Key SELECT NewGroup

// The type of oCount is IOrderedEnumerable<<IGrouping<string,Developer>>

// We prefer the VAR keyword!

WriteLine(e"X# does LINQ!\n")

WriteLine(e"All X# developers (country+lastname order)\n")

FOREACH VAR oDeveloper IN oAll

WriteLine("{0} in {1}, {2}",oDeveloper:Name,oDeveloper:Country,oDeveloper:Region)

NEXT

WriteLine(e"\nGreek X# Developers (descending lastname)\n")

FOREACH oDeveloper AS Developer IN oGreek

WriteLine(oDeveloper:Name)

NEXT

WriteLine(e"\nDevelopers grouped per country\n")

FOREACH VAR country IN oCount

WriteLine(i"{country.Key}, {country.Count()} developer(s)")

FOREACH VAR oDeveloper IN country

WriteLine(" " + oDeveloper:Name)

NEXT

NEXT

WriteLine("Enter to continue")

ReadLine()

RETURN

FUNCTION GetDevelopers AS IList<Developer>

// This function uses a collection initializer for the List of Developers

// and Object initializers for the Developer Objects

VAR oList := List<Developer>{} { ;

Developer{}{ FirstName := "Chris", LastName := "Pyrgas", Country := "Greece"},;

Developer{}{ FirstName := "Robert", LastName := "van der Hulst", Country := "The Netherlands"},;

Developer{}{ FirstName := "Fabrice", LastName := "Foray", Country := "France"},;

Developer{}{ FirstName := "Nikos", LastName := "Kokkalis", Country := "Greece"} ;

}

RETURN oList

FUNCTION GetCountries AS IList<Country>

// This function uses a collection initializer for the List of Counties

// and Object initializers for the Country Objects

VAR oList := List<Country>{}{ ;

Country{} {Name := "Greece", Region := "South East Europe"},;

Country{} {Name := "France", Region := "West Europe"},;

Country{} {Name := "The Netherlands", Region := "North West Europe"} ;

}

RETURN oList

CLASS Developer

PROPERTY Name AS STRING GET FirstName + " " + LastName

PROPERTY FirstName AS STRING AUTO

PROPERTY LastName AS STRING AUTO

PROPERTY Country AS STRING AUTO

END CLASS

CLASS Country

PROPERTY Name AS STRING AUTO

PROPERTY Region AS STRING AUTO

END CLASS

PHH - 12th. November 2016.


General - Instantiating Class Objects, in various ways

General - Instantiating Class Objects, in various ways

General - Instantiating Class Objects, in various ways

 Previous topic Next topic

Since I started coding in X# some weeks ago, possibly a month, there have been some very

useful changes and updates to the compiler by Robert and his team.

We need to know just what these changes are and how to use them to make our coding life

easier, as well as more rewarding on a design and use point of view.

Many of the changes the Team has made can be beneficially used when programming LINQ stuff.

Robert said this to me very recently :-

It has lots of fixes and new features compared to the last public beta. Some new features that

we discussed on the forum and that may be interesting to you and that you can use in your examples

to show our progress ;) :

ℜ• Fix for the problem with the LINQ join clause

ℜ• Added Collection Initializers

ℜ• Added Object Initializers

ℜ• Anonymous type members no longer have to be named. If you select a property as an anonymous

type member then the same property name will be used for the anonymous type as well.

The attached example uses all of these (compile in Core dialect) - this is shown in full in the previous

sub-section from here.

Some other changes:

- We have added a .config file to the exe for the shared compiler that should make it faster

- Many changes in the VO/Vulcan compatibility area

Robert

*** NOTE *** The attached example uses all of these (compile in Core dialect) - Robert posted!

===============================================================================

Well folks we have some nice 'extra' ways to instantiate objects and initialize collections in the recent X# compiler.

This also extends to Anonymous types, which are more than useful when it comes to LINQ and handling our data

collections in X# .NET.

First lets see a basic business class of mine :

I will keep it as simple as possible so that you can see exactly what is going on.

If this was a class that I needed to use in my business app solution then I would add extra 'bite' to make it

work with WPF data binding as well as LINQ with Entity Framework.

But for now a simple class definition will serve us well. Checkout below :-

==========================================================================

We have a single Constructor which sets each property to a default initial value - not a lot of use really,

but it is a habit of mine NOT to leave properties unassigned.

We may need to change this the more we use LINQ with SQL and Entities. As NULLs are an integral

part of SQL 'life'.

Now the above class is upgraded to be usable with SQL Table data - reading in, and writing out of the application.

"Rule One for SQL work - deal properly and correctly with NULLs."

==============================================================================

If you are going to use 'L2S' and/or 'L2E' then you had better get used to 'Nullable' types.

Note you can't do this for Strings as we get a compile error. A string can be NULL as we will

see later in this section.

Lets move on ......................

The standard (basic) ways to instantiate a business object :

Let us now use this simple Class to see how we can instantiate an object in code. The easy and common way.

Check the following image to see our first test and what we get at runtime :-

=======================================================================================================

Doing things the above way we get a new object of our class which has all the default values set to the named properties.

So printing out one like 'LastUsedDate' provides the screen display seen above.

Now then, lets keep the Class definition as it is, but assign other values of our own to the properties :-

=====================================================================================================================

Yes, this all works well and we should all be familiar with this simple approach.

But what about taking things further ? Lets start a new sub-section seen below .............

Basic - Using Input Parameters :

Let us now create in our code of the Class, a second Constructor which accepts input parameters :-

[ .. study lines 220 through 227 .. ]

====================================================================================================================

Okay guys, we can now use the second Constructor overload to do something like what is seen in the next image :-

=====================================================================================================================

However, we need to provide each and every input parameter for the overload, as well as having them in the right order.

Study the following details :-

====================================================================================================================

One problem I have with this is that items are 'positional', and by this I mean the meaning of the value simply depends on where

it is in the order - where it is in the input data order.

But we can improve this as seen in the next example :-

[ .. there are reasons I don't really like the following, but it works .. ]

================================================================================================================================================================================

I don't wish that my internal variable names for my Constructor parameters are used in this way - I wish to keep them

internal to my Class code.

After all we have property names and I would personally prefer to use those.

First lets do a further test with this current way of instantiating an object.

Lets provide the input parameters in some sort of random order, which at least gets us away from the 'positional' issue :-

=================================================================================================================================================================================

Yes, above we get the correct values to the properties but in a non-specific order of assignment.

Currently, with the examples seen above, we are using the simple property definition types, not the Nullable ones.

Here is what we have been using for the last example / test :-

=======================================================================================================================

We could do the same with Nullable Types if we chose, but lets instead see the Class as I have defined it for use with the

LINQ to SQL examples - check below :-

=========================================================================================================================================

Okay, that is fine, let now move on a pace or two .......................

The new way using 'Object Initializer' :

This is one recent thing which Robert and his Team have added into the X# compiler.

Lets first see the 'Object Initialiser' in use in working, compilable code :-

=========================================================================================================================

Notice that using our Class type 'CustomerItem2' we can define the properties to be Null if we so wish.

Note that the basic structure is " CustomerItem2{ } { } ", and yes, there is a second pair of curly braces.

Lets make a nice trial by commenting out the Constructor, and trying the same runtime code - see below :-

=========================================================================================================

We are not using a Constructor but by the new allowable syntax providing instead property values to named specific properties.

(One or more properties.)

Here it is again with the comments hidden :-

==============================================================================

So lets use this for a VERY simple test - check this out :-

=====================================================================================================================================

;-0) .. for all those C# haters, there are only SIX curly braces on line 122 in our nice X# syntax ;-0))

If we have done things as I wished / planned, we should now have a new object, with one property value and the rest should be

unassigned, or in SQL terms, 'Null's.

We can extend this simple test by outputting a property we have not as yet assigned - study the following image details :-

====================================================================================================================

Yes, folks, the empty message box means we have got a 'Null'.

But what if we wish to print out our string value assigned to the 'ProductCode' property - remember

this is not defined as 'Nullable<string>'.

This is what we get :-

==========================================================================================

Oh! - common stuff - handling nulls once more ;-0) We have needed to do that (handle nulls) a time or two in our coding.

The following is NOT permitted :-

=============================================================================

As we can see by this error message :-

==================================================================================================================================================

So we need to handle null stuff ourselves. Try checking out the follow code :-

==================================================================================================================================

The above code lets us detect the presence of a Null before we try and use it. Yes, standard strings can be 'NULL' - a good

thing to remember when doing LINQ and SQL stuff.

I don't like the non-SQL approach of .NET talking of something being equal to 'null'. Its not the NULL way of thinking, but

we are stuck with it. Something can only be equal to something else if both 'things' have a value. And NULL is not a value,

it is 'undetermined'.

Lets move on ..............

Collection object - Instantiation and Initializing :

As you know by now, 'Collections' play a BIG part in modern .NET programming.

We need to use collections most of the time, some would say 'all of the time'.

So it is nice to have an easy syntax for instantiating and initialising them - along the lines of some of

what we have already seen above.

Lets go straight away to seeing an example of a collection of 'CustomerItem' elements. Personally, I

like to talk about a collection of items, but we may have too many 'item' words in my example 'wording' here if

I do ;-0)

============================================================================================================================================================

[ We now have lots of ways of declaring our local variable, and I feel that each has its place in my coding. ]

Yes, this is pretty nice and very much in line with what Microsoft does with C# - how we construct our collection..

Its great to have this now in X# - well done Robert and the Team.

Lets display our newly made collection, using our WPF form (DataGrid) control - see below :-

================================================================================================

And now we need to explore a little more how we can layout the code within the required syntax, so we can see it more clearly perhaps :-

============================================================================================================================================================================

Yes, I know, you will need some time and experimentation with important commas and semi-colons. Oh! and the nice curly brace, or two ;-0)

But it all is pretty straight forward and makes good sense I feel.

And it works !

Lets move on .....................

Anonymous Types (ATs) - Instantiation :

Like them (or the idea of them) or loath them, in modern .NET coding we need to use them (ATs), at least sometimes.

So this means we need to know what they (ATs) are and how best to use them - and even possibly when to try and

avoid using them ;-0)

BUT - we can't ignore them as professional coders.

In particular, when we do LINQ coding we very often need to do our selecting of fields/columns using ATs.

To those of you who are new to Anonymous Types, the idea is really quite simple. Yes, simple.

In our code we can define and initialise a Class with no name - so in the sense that a person is anonymous if

we don't know who they are, then a 'nameless' Class is an AT.

To declare an AT we need to specify its properties, and to assign these a value. Remember, no name.

Before we talk any further / longer, lets see a working example - check out line 133 below :-

==========================================================================================================================

The variable has a name but the Class does not - the variable is an object with 'no name' - anonymous.

So in the code above we have made an object with three properties, 'Name', 'Number', and 'ATdate'.

We have also assigned values to these properties.

Note that we could have done this in any order of the properties, the result would be the same.

Lets print out some details of the object we have created in our code :-

==========================================================================================================================

Yes, the above screen display shows the values of the three properties - shown singly at the end of the text string.

Lets now go a step further and make a CLASS (AT) from properties of one or more existing objects, rather than a hard

wired name and value for each property.

Check out these details very carefully :-

==========================================================================================================================================

Notice that the names of the properties shown have also been hard coded by our own hand.

Here is the isolated section of the LINQ query code :-

==================================================================================================================================

And before we go any further, lets make this more clear to the reader by adding some organised structure into our code.

Study this carefully - lines 337 to 344 :-

============================================================================================================

However, we can simplify this code quite a lot, provided that we are happy to have the name of the new property in the AT Class the

very same as the name in the class from which we are assigning the value.

See how much neater and clearer this is in the next image :-

=====================================================================================================================================

In the above image see how the column headers in the data grid are now changed to those property names of the originating

object properties.

Probably this is the way many of us will do it, most of the time in our application solutions.

So above, our originating objects are two, one a 'Customer' object, and the other a 'CustomerItem' object.

The properties are pretty obvious to see ..........

Time to move on, see you in the next section.

PHH - 15th. & 17th. November 2016.

Addendum : - "Mix and Match" :

Oh! - I should have said that we can also mix the way we declare our properties, and how they are named.

This may seem pretty obvious to many of us - BUT - it does need saying as it is a big part of what is possible.

Lets see what I mean by looking at an example - see and study the image details below :-

==========================================================================================================================

In the code lines above from 372 through 379 we have a mixture of default property names as well as defined property names.

I have chosen 'Code', 'Tot', 'Last', and 'First'. The rest are to take the default names - that is those names as used for properties

in the originating objects where the values are stored. In our case 'c' and 'ci', which are 'Customer' class and

'CustomerItem' class objects.

Please note that a point (full stop) can't be added to the total heading, so we can't have 'Tot.' Rules of naming properties, and

characters which are not allowed.

Lets move on ...............

PHH - 18th. November 2016.


Generics - getting started in X#

Generics - getting started in X#

Generics - getting started in X#

 Previous topic Next topic

This is useful, even though it is in C# syntax :-

https://www.tutorialspoint.com/csharp/csharp_generics.htm

==============================================================================

Okay guys, lets make this topic as easy as possible. It is NOT difficult if tackled right.

What technology Microsoft builds for us is usually much simpler than a lot of authors make it sound / seem.

Many eBook articles, and web articles, get us lost in the details of doing stuff, and forget to make the overall

pattern of things understandable. We need to see the bigger picture.

Also poor examples can just muddy the waters.

We need to know what Generics is, and what the technology can do for us. Then find a few good

and straight forward examples.

We also need to draw some useful and appropriate parallels with what we already know and use.

Eventually, we will be able to design and create our own generic classes (types), methods, interfaces,

events, and delegates. There is a lot in common for each of these, so its not as bad as you think.

Lets get our sleeves rolled up and make a start ;-0)

===========================================================================

What is Generics ? - a simple answer :

The technology of Generics allows us to write .NET code such that class 'Types' are supplied at runtime

and not hard coded.

So we can write methods (and other members) which have code which refers to a general 'Type' and the

Type is provided at runtime in a similar way to the values of variables we use as parameters to methods

and procedures.

By supplying runtime 'Types' we can reuse code over, and over - for different Types. In a similar way to

the way using methods and parameters saves us lots of lines of code when variable input parameters get

different values assigned during code execution.

So for a while we all have had 'data item passing', and now with Generics we have 'Type passing'.

We must.nt think that Generics is much more than that, even though its impact can be great.

Lets look at some general X# syntax for before and after Generics are used.

*** NOTE *** It has been hard for me to find in my current coding, a suitable sample without Generics

being involved somewhere in the code syntax !!!

Here is one of the few old style methods I could find :-

===========================================================================================

Notice above that we have data parameters being passed in and through the method code - in at

line 163 and then out to other methods in lines like 166 and 174.

Here below is a simple 'Initialise' method I wrote for a demo app for Cologne 2017, we now see on line

60 the use of a Generic type provided by the framework. Always look for ' < > '.

So on line 60 the Type(s) are placed between the ' < > ' and the data item parameters between the ' ( ) ' :-

====================================================================================================

Out of interest, while looking for some standard non-Generic code syntax, I found it very difficult to find any.

I really had no idea that I had come to use Generic types with my MVVM pattern of design. Its everywhere!

This probably means that I am doing something right ;-0)

In-built Generics within the .NET framework :

In the past with .NET, before Generics was introduced, the performance of using collections was degraded,

or compromised, because collection items needed to be cast and recast as items in a collection were accessed.

We now have available to us in current .NET frameworks the 'System.Collections.Generic' namespace, which

exists in the assembly named 'System'.

Lets look at System with the Object Browser in Visual Studio 2017 :-

==========================================

And now if we expand the tree further we see that the 'Generic' items comes

to this shown below :-

=====================================================================

Do NOT panic, some of this will become more understandable as we progress through

these learning eNotes.

Lets first of all see if we can use a very commonly used class type from within the Generic namespace.

I use ' List<T> ' a great deal when I use LINQ to process my data in collections.

My use is likely to be ' List<int> ', 'List<string>', or more likely ' List<Customer> ', when doing business code logic.

Lets now study some code .............. and suitable examples ............

It is very easy to USE the Generic types in code, but a little more work to CREATE our own Generic types,

or classes. Remember that Types and Classes are the same thing.

In my search for some suitable X# code syntax I found the following business data 'Model' class, part of

the 'Stock System' app I wrote for Cologne. Check below to see just how many lines have the Generic

'sharp pointy' brackets (or chevrons) :-

=====================================================================================================

The number count is just about 50 / 50 for lines that are related to generics.

What is going to be the hardest part of using Generics ? :

This seems as if it may be a complicated question, or even one impossible to answer.

Well, I think the answer is simple - it is knowing when to apply our own Generic code for our own

business classes and methods.

There are quite a few simple samples around, which unfortunately are not much use in guiding us as

to how and when to do Generics for our business app logic.

For myself, as I see things at the moment, the BIG step for anyone is to start using the easy to access

Generics from the framework, and apply it to each and every collection we create and use.

Then as we gain more experience we will also see some better examples from others, and then off

we shall go ;-0)

Be careful that you do not invent the wheel with Generics, and do your own coding when in fact stuff

already is there in the framework, for us to use right off the shelf.

PHH - 22nd March 2017.


Information in MSDN help notes

Information in MSDN help notes

Information in MSDN help notes

 Previous topic Next topic

Here are a few useful snippets from the Generics help details - read them to get our brain

thinking the right way before we try and make some of our own Classes and Methods.

===============================================================================================================

===============================================================================================================

=================================================================================================================

==============================================================================================================

==================================================================================================================

=========================================================================================

=================================================================================================================

=================================================================================================================

===========================================================================================================

*** NOTE *** I am not sure I quite understand the above note !? I will work and think on this.

================================================================================================

PHH - 23rd. March 2017.


A full but simple example

A full but simple example

A full but simple example

 Previous topic Next topic

PHH - 23rd. March 2017.


Some simple basic rules and thoughts

Some simple basic rules and thoughts

Some simple basic rules and thoughts

 Previous topic Next topic

When coding our own Generic members - classes, methods, interfaces etc., takes these

rules of thumb into account :-

- Although many samples show just one 'T' or Type in the chevrons ' < > ' we can in fact have many.

Here is a working example with two :-

================================================================

- Although it is common to use 'T' for a type, or something similar 'T2', 'TVal' etc., it

is only convention. We can use anything as the textual 'place-holder'.

Here is one I did recently :-

Whatever we do use, we must then follow it through with all the code, obviously !

So we see this in the Constructor as well :-

=============================================================================================

- Although I have not seen any examples showing 'Overloading' we can do it successfully, just

in the same way as we do for parameters in our methods and classes, etc..

The following overloading compiles and runs :-

=========================================================================================================

The only real difference for Classes is that the signature is in the class definition and not the Constructor, as

it is when we overload using parameter signatures.

Here is an example Method definition, with types and data parameters together in the signature definition line :-

=====================================================================================================================================

- As with parameter overloading, we can't have two definitions with the same signature.

For Generics that simply means the number of Types. Since the text used in the Types placed in the signature,

then it is ONLY the number of types which counts.

======================================================================================================

=========================================================================================================================

====================================================================================================================================================================

=======================================================================================================================

- Although it may be a little early in our studying of Generics, we can 'Nest' generic types.

Or, more correctly say 'wrap' them - we shall see when we try some code .....

By nest / wrap, I mean place an already defined type within the definition / specification of another - hard to get your head

around this, then look at an example :-

======================================================================================================

The above compiles and so we have the correct syntax.

Lets try and add some code to allow us to run the test method, as well as output some simple

message text to show we have actually visited and run the code :-

=================================================================================================

And now the updated code and the runtime 'proof ' :-

=====================================================================================================================================

Okay guys, it can appear confusing to us who are new to Generics, but it is not either magic nor rocket science.

We just need some experience and practise at coding such stuff.

We also just need to remember that the 'T' or whatever text we use is just a 'placeholder' until runtime.

We also need to remember that in multiple Type specifications, we can often have duplicate Types. By this I mean

if in input parameter terms we can have :-

========================================================================================================================

Yes, above we have three input parameters, each of data type 'string'. Not unusual, so why not :-

==============================================================================================================================================

================================================================================================================================================

CARE >>> it seems to me to feel wrong if we know at time of coding what the Type maybe.

The whole point of Generics is to code things NOT knowing what the type will be.

I can see that some newbies to Generics may try to use it when in fact they don't require it !!!

Obviously, we have to use the correct and suitable syntax within the body of our Generic method.

This is where we need to stop trying to explain and where good and meaningful examples take over.

I will ask the community for their ideas through the X# Forum.

For now here is another example to thing about - it compiles okay :-

============================================================================================================================

Notice how we can use the Types within the list of parameter definitions.

Lets try a simple test, check these details :-

========================================================================================================================================================

And the calling code is as shown below :-

====================================================

We can now look at some cases where we get the coding wrong, simply because we anticipate one way we

may use the Generic member.

With the above test code in mind, lets try this code in our method :-

=========================================================================================================================================

Yes, we are not allowed to cast with Types that are undetermined at compile time.

And here is another case which makes sense that it is not allowed :-

============================================================================================================================================

I think what we all should do is go and carefully examine the Generic types already defined for us in the

new frameworks provided in the latest .NET version.

I would hazard a guess that Microsoft have done most of the work for us.

Lets start by maximising the performance of our Collections by using stuff like 'List<Customer>()' in place of 'List()'.

So to me the BIG question is not what can we do with Generics BUT what should we be doing in our business solutions with Generics.

Lets move on to another sub-section .........................

PHH - 23rd. March 2017.


A more complex sample

A more complex sample

A more complex sample

Previous topic Next topic

PHH - 23rd. March 2017.


Tuples - what they are and how to use them

Tuples - what they are and how to use them

Tuples - what they are and how to use them

 Previous topic Next topic

Here is a useful web link :-

https://msdn.microsoft.com/en-us/library/dd414846(v=vs.110).aspx

It says this :-

- To represent a single set of data. One data record, with fields.

- To provide easy to, and manipulation of, a full data set. Many records (rows) of data.

- To return multiple values from a method without the use of out parameter in C#.

- To pass multiple values to a method through a single parameter.

Tuples being structures makes the 'light weight'.

We need to check on how to use 'out' in X# syntax.

PHH - 24th. March 2017.


'Project' - a full demo interactive 'Stock' application

'Project' - a full demo interactive 'Stock' application

'Project' - a full demo interactive 'Stock' application

 Previous topic Next topic

Like a lot of things in Research and Development, this project application, although well on the way to

completion, is actually still unfinished.

I need to write about some of it before I can find the time to complete the remaining parts.

Most of what exists now is very useful to us guys new to LINQ and EF6, as well as MVVM and WPF/XAML

as well as data binding.

Here is how the main launch form/window looks at the moment :-

=========================================================================================================

Within the existing code of this demo 'Stock' application we have lots of useful samples, ones we can copy

and adapt to suit our own developing needs.

PHH - 11th. January 2017.


The software technologies used

The software technologies used

The software technologies used

 Previous topic Next topic

One of the main focuses of this software 'project' is the X# language itself.

X# is a creation of Robert and his small Team, and presumably belongs to them, even though they

make some versions of the compiler open to many of us developers.

However, it has to be realised that by Microsoft making its 'Roslyn' compiler open to the public, it

was what has made X# what it is today. Without Roslyn we would have no LINQ, as well as many other

tried and tested features of of the Microsoft C# .NET language.

It is because of what Roslyn opened up to the X# language that made me move over to use it, previously

I had been using C# for quite a few years. Once I discovered LINQ some six or more years ago I moved

over to C# because it was so good to use with LINQ to SQL and Entity Framework 6.

Now I can move back again and still have all these features and facilities from an xBase platform.

So when we are discussing the software technologies used here by myself, I am talking about WPF with XAML,

data binding in WPF / XAML, LINQ for all types of collections, and Entity Framework, 6 and onwards.

All of these are creations of Microsoft - and now open to us in X# .

===================================================================================

MVVM which we have discussed much in the last few years is a 'Pattern' of development, rather than a technology,

and originates with one guy - a chap from Switzerland I believe. Laurent Bugnion of his own 'GalaSoft' company.

There are a few frameworks for MVVM, but the underlying 'theme' or 'style' is consistent. More about this

in the next sub-section.

===================================================================================

In the development of this 'Stock' application I will partly apply the MVVM approach, partly because I like it, and

think that the 'View' and supporting 'ViewModel' architecture make data binding easier to apply, and also only

'partly' because we wish to keep this project as simple as possible, so readers can clearly see what I have done with

the other parts of the focus on 'data binding' and the use of LINQ and EF6.

Personally, I feel that XPF/XAML, data binding in WPF, LINQ and Entity Framework should all be used together, with

the MVVM pattern.

It works for me, and I like it a lot.

Lets move on and make some progress ................

PHH - 11th. January 2017.


Development 'pattern' part used - MVVM etc.

Development 'pattern' part used - MVVM etc.

 Previous topic Next topic

Development 'pattern' part used - MVVM etc.

 Previous topic Next topic

===================================================

PHH - 11th. January 2017.


Events - how they are handled

Events - how they are handled

Events - how they are handled

 Previous topic Next topic

Okay then guys, in these days of modern .NET coding we have a conflict, or tension.

We need events to fire on our View, but we don't wish to have any event handling code in the

'code behind'. We need any such method code to be within the ViewModel, for Unit testing requirements.

========================================

===========================================================================================

PHH - 11th. January 2017.


Using 'Commands' - towards MVVM

Using 'Commands' - towards MVVM

Using 'Commands' - towards MVVM

 Previous topic Next topic

When moving towards implementing the MVVM pattern of application design we must keep our 'code

behind' file as clean and as empty as possible.

This simply means to me and you that we do NOT have event handler methods in code behind.

Here is the code behind associated with the 'View' called 'AddOrders'.

Check this for simplicity :-

===================================================================

So where is the code to handle the push 'Button' click events I am using ?

Well, it is now conveniently within the 'ViewModel' code section.

==============================================================================================================

=============================================================================================================

=============================================================================

=====================================================

=====================================================================================================================

====================================================================================================================

==============================================================================================================

PHH - 11th. January 2017.


the 'RelayCommand' class

the 'RelayCommand' class

the 'RelayCommand' class

 Previous topic Next topic

This class originally came from an example in "C# Corner".

I adapted it and used it successfully without making many changes.

To make the 'RelayCommand' work for us we use the 'Command' attribute which is available for the

Button class in WPF, but unfortunately, not a lot more - of the tools in the WPF toolbox.

Remember, we are trying to keep our code within the ViewModel class, and placing virtually nothing

in the 'code behind' the Form itself.

https://msdn.microsoft.com/en-us/magazine/dn237302.aspx

========================================================================================================

======================================

=====================================================================================================

PHH - 19th. January 2017.


The 'EventToCommand' ...

The 'EventToCommand' ...

 Previous topic Next topic

The 'EventToCommand' ...

 Previous topic Next topic

https://msdn.microsoft.com/en-us/magazine/dn237302.aspx

======================================================================================================

===================================================================================================

PHH - 23rd. January 2017.


Saving a new 'OrderLine', with checking ...

Saving a new 'OrderLine', with checking ...

Previous topic Next topic

Saving a new 'OrderLine', with checking ...

Previous topic Next topic

Okay then guys, lets deal with the attempted saving of a newly in-putted 'OrderLine.

To make our application more robust when it comes to creating a new 'Order' for a customer,

we do need to check that we have a genuine and useful new entry.

We do not wish to have blank / empty entries saved, or ones without an appropriate Product item

selected.

We also need to do some checking on the value of the quantity provided, as well.

Yes, basic stock type checking.

First the value of the quantity - I have chosen from 1 to 9 as a reasonable value for my app.

This disallows the obvious 'zero' as well as double digit entries so that '11' and '33' are disallowed.

Multiple key 'hits' are therefore filtered out.

Then secondly, on line 280 we see a check for non-zero Product identity.

Check the details shown below :-

=======================================================================================================

In the above code lines 287 through 292 finds and disallows any duplicate product entries.

The code shown above is the old fashioned way to loop through 'stuff'.

Lets try and improve the code shown above, or should we say make it more 'modern'.

Remember my quest is to remove as many 'LOOPS' from my own code as possible - I am not

worried about what is actually behind my application code, as long as Microsoft makes it work.

Removing top level code for/loops makes our code more descriptive and maintainable.

The LINQ and 'extension method' approach to coding is to replace the older fashioned code

shown below :-

====================================================================================

The 'query' line shown below is a single 'complete' line (287 through 289) :-

=========================================================================================

The code can be read as ... "... extract the items from the collection, where the identity property of the item is

equal to the identity property of the selected Product, and take only one item or the default. Compare this item

with 'null' ... "

This means that the result of the query is a Boolean - True or False.

It will be TRUE when we have a duplicate item.

Here we can see it being tested out at runtime :-

[ .. we have to try and make a duplicate entry to force the 'True' result .. ]

=================================================================================

We will remove or comment the message dialog once the testing is done.

Lets experiment with spacing this single long query line, to make it a bit more readable :-

[ .. not perfect but an improvement perhaps .. ]

=======================================================================================

In fact using 'ol' in place of 'o' seems a better idea to me.

Nick's first C# code probably used 'o' for object when in fact I wish to make sure it is not taken

for 'Order'.

The items are actually 'OrderLine' objects and so it seems a better idea to use 'ol' - see below :-

So the items in the collection aOrderLines are of type 'OrderLine'.

Lets move on ...................

PHH - 23rd. January 2016.


"Data Binding" - the 'what, the where, and the why'

"Data Binding" - the 'what, the where, and the why'

"Data Binding" - the 'what, the where, and the why'

 Previous topic Next topic

==============================================================================

============================================================================================================================================

===================================================================================

========================================================================================

=======================================================================================================================================

PHH - 11th. January 2017.


The SE Pane - solution structure

The SE Pane - solution structure

The SE Pane - solution structure

 Previous topic Next topic

=========================================

==================================================

PHH - 11th. January 2017.


The 'Main' window form

The 'Main' window form

The 'Main' window form

 Previous topic Next topic

PHH - 11th. January 2017.


Entity forms

Entity forms

Entity forms

 Previous topic Next topic

=======================================================================================

=======================================================================================================================

========================================================================================

PHH - 11th. January 2017.


Data entry forms

Data entry forms

Data entry forms

 Previous topic Next topic

=======================================================================================

===============================================================================================

===========================================================================================================================================

PHH - 11th. January 2017.


Adding 'OrderLines' to a new Order

Adding 'OrderLines' to a new Order

Adding 'OrderLines' to a new Order

 Previous topic Next topic

==============================================================================================================

===========================================================================================================

=========================================================================================

========================================================================================

===================================================================================================================

PHH - 23rd. January 2017.


View All LINQ queries - form

View All LINQ queries - form

View All LINQ queries - form

 Previous topic Next topic

==============================================================================================================

===============================================================================================================================================

======================================================

PHH - 11th. January 2017.


Re-creating the 'Code First' database

Re-creating the 'Code First' database

Re-creating the 'Code First' database

 Previous topic Next topic

====================================

PHH - 11th. January 2017.


Editing existing Entities

Editing existing Entities

Editing existing Entities

 Previous topic Next topic

PHH - 31st. January 2017.


Deleting / Removing, existing Entities

Deleting / Removing, existing Entities

Deleting / Removing, existing Entities

 Previous topic Next topic

===================================================================

===========================================================================================================================

PHH - 31st. January 2017.


Enums in use - with Masking and Validation

Enums in use - with Masking and Validation

Enums in use - with Masking and Validation

 Previous topic Next topic

The .NET framework makes great use of Enums, and we will need to use these, whether we like it or not!

We have no choice but to use System enums - AND - if we are wise, we will make a few of our own as well.

Simply put, Enums make our programming and coding life easier. As well as making our code more readable.

===================================================================================================================================

====================================================================================

=======================================================================================================

===================================================================

========================================================================================================================

===================================================================================================================================================================

==============================

=================================================================================

==================================================================================================================================================================

PHH - 20th. February 2017.


the .NET 'Enum' class

the .NET 'Enum' class

the .NET 'Enum' class

 Previous topic Next topic

Lets look at what the Developer Network documentation has to say - we will pick out just the basic parts :-

==================================================================================================

And now lets see the STATIC methods which will provide us with most of our usable functionality :-

[ ... in our examples we will see most of these in action ... ]

=========================================================================================================================================

PHH - 20th. February 2017.


samples - a start

samples - a start

samples - a start

 Previous topic Next topic

Lets make a start at discussing Enums and how I have recently been using them in my code.

I have been exporting older Vulcan code into X# ready for the Cologne 2017 conference.

Part of the Validation app from last year's conference (April 2016) uses a 'Mask' approach to an input TextBox

control on a WPF form.

Although I have not applied a 'Converter' to clean the value entered (but this is quite possible), the code I have

checks the data entered at the keyboard and informs the user if it is not compliant with the mask definition.

Lets us see a visual example - below is such a runtime situation :-

=================================================

In the XAML script shown below we see a wavy line - BUT - in fact it is not an error but is an issue caused by the current version

of the VS integration into VS 2017 RC. The script and code compiles and runs 100% a-okay!

==============================================================================================================================

So then folks, lets get to some Enum 'stuff'.

Here is an Enum of my own that I use with the Mask input code :-

[ .. note that some lines are collapsed, and they are similar to what is seen .. ]

===================================================

You may have noticed that the numeric part is actually one number representing two parts.

The first digit represents the number of alphabetic characters - shown as 'X's and the second,

or right hand digit represents the number of numeric digits.

So 22 would be represented as 'XXNN' and in the mask format this would be ' XX.NN ' which has

a dot (or point) between the characters and the digits.

Lets start to view and study some X# .NET code.

We will start coding examples by using one or two of the STATIC methods shown in the previous sub-section.

These static methods facilitate us when it comes to needs of manipulation of 'enum' members, their values, and

also their names.

Study the following image to see 'GetValues' in use as well as 'Cast()' and 'ToList()' extension methods :-

==============================================================================================================================================================

=========================================================================================================

PHH - 20th. February 2017.


samples - going further

samples - going further

samples - going further

 Previous topic Next topic

================================================================================

====================================================================================================================

==============================================================================

=====================================================================================================================

=====================================================================================================================

PHH - 20th. February 2017.


samples - more advanced

samples - more advanced

samples - more advanced

 Previous topic Next topic

=============================================================================================================

PHH - 20th. February 2017.


samples - standard .NET enums

samples - standard .NET enums

samples - standard .NET enums

 Previous topic Next topic

==================================================================================================================================================================

==========================================================================================================================================================================

======================================================================================================================================================================

=======================================================================================================================================================================

===============================================

====================================================================================================================================

PHH - 20th. February 2017.


Assemblies & Namespaces

Assemblies & Namespaces

 Previous topic This is the last topic

Assemblies & Namespaces

 Previous topic This is the last topic

========================================================================================================================================================================

=============================================

================================================================================

======================================================

====================================================================================================================================================

PHH - 20th. February 2017.