Friday, 9 May 2014

What is Magic Table in SQL Server?

Introduction

Here, I will explain what is Magic Table and how to get this in SQL Server.

Magic Table

The tables “Inserted” and “Deleted” are called magic tables of the SQL Server. We cannot see these tables in the database, but we can access these tables from the “Trigger”. These tables are automatically created and managed by SQL Server internally to hold recently inserted, deleted and updated values during DML operations (Insert, Update, Delete) on a database table.

Use of Logical Tables

Generally, logical tables are used by triggers for the following purposes:
  1. To identify data, which is error free?
  2. To check the effect of data on the table

Inserted Logic Table

When we insert the record into the table, the magic table “Inserted” will be created and that table holds the current inserted row. We can access their record using “Trigger”.

Create LogMessage Table 

Create table LogMessage (Empid varchar(4),EmpName varchar(50),Message varchar(50))
what is magic table.

Create Emp Table 

Create table Emp (Empid varchar(4),EmpName varchar(50)) 
what is magic table.

Create Trigger For Display Current Inserted Row

Create Trigger LogDisplay
On Emp
for Insert
As
Select * from Inserted
Select * from Deleted
Go 
what is magic table.

Create Trigger

Create Trigger LogInserted
On Emp
for Insert
As
Declare @EmpId varchar(4)
Declare @EmpName varchar(50)
Select @EmpId=(Select EmpId from Inserted)--get data for Inserted Logic Table
Select @EmpName=(Select Empname from Inserted) )--get data for Inserted Logic Table
Insert into LogTable (EmpId,EmpName,Message) values(@EmpId,@EmpName,'Record Added') --Save Current row in LogTable
Go 
what is magic table.

Insert a Row in Emp Table

Insert into Emp (EmpId,EmpName) values('S001','Ravindra')

Here Two Triggers are Fired

  1. LogDisplay
  2. LogInserted
what is magic table.

Deleted Logic Table

When we delete the record from the table, the magic table “Deleted” will be created and hold the current deleted row. We can also access these rows from “trigger”.

Create Trigger for Display Current Deleted Row

Create Trigger LogDisplayDel
On Emp
for Delete
As
Select * from Inserted
Select * from Deleted
Go 
what is magic table.

Create Trigger

reate Trigger LogDelete
On Emp
for Delete
As
Declare @EmpId varchar(4)
Declare @EmpName varchar(50)
Select @EmpId=(Select EmpId from Deleted)
Select @EmpName=(Select Empname from Deleted)
Insert into LogTable (EmpId,EmpName,Message) values(@EmpId,@EmpName,'Record Deleted')
Go 
what is magic table.

Delete a Row in Emp Table

Delete from Emp where Empid='s001' 
what is magic table.
We could not create the logical tables or modify the data within the logical tables.

Traction History

select * from logTable 
what is magic table.
Note: If you are use Truncate command, then no Trigger fired.
truncate table Emp   

 

 

 

Generating a Sequence in SQL

Introduction

I came through one of the many interesting SQL questions on one of the forums yesterday. The original poster of the question wanted to get a list of the next 15 dates starting today. And he wanted to do this by using cursors. While you can write a cursor to get the results in this case, cursors are not meant to be used like this. A cursor is used to step through the results of a query that returns multiple results, e.g., rows from a table. One good old way of generating a sequence of next n dates would be to use the WHILE loop in SQL.

    DECLARE @LoopCount INT
    SET @LoopCount = 0
     
    DECLARE @calcDate DateTime
    SET @calcDate = GETDATE() 

    DECLARE @outDate varchar(30) 

    WHILE @LoopCount < 15
    BEGIN
     
         SET @outDate = CONVERT(NVARCHAR, @calcDate, 103) 
         PRINT @outDate
         SET @calcDate = DATEADD(dd, 1, @calcDate) 

         SET @LoopCount = @LoopCount + 1
    END

Generating a Sequence of Dates in SQL

Another better alternative would be to use the Common Table Expressions in SQL Server.
A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. A CTE is similar to a derived table in that it is not stored as an object and lasts only for the duration of the query. Unlike a derived table, a CTE can be self-referencing and can be referenced multiple times in the same query.

    WITH q AS
        (
        SELECT  GETDATE() AS datum
        UNION ALL
        SELECT  datum + 1
        FROM    q
        WHERE datum + 1 < GETDATE() + 15
        )
    SELECT  CONVERT(NVARCHAR, DATEADD(dd, DATEDIFF(dd, 0, datum), 0), 103) AS MyDate
    FROM    q

Generating a Sequence of Numbers in SQL

Similarly, you can generate the sequence of numbers in SQL using the Common Table Expressions.

    WITH q AS
        (
        SELECT  1 AS num
        UNION ALL
        SELECT  num + 1
        FROM    q
        WHERE num < 15
        )
    SELECT  * FROM    q

Generating a Sequence of Alphabets in SQL

Or, you can even generate the sequence of alphabets in SQL using the Common Table Expressions.

WITH q AS
        (
        SELECT  0 AS num
        UNION ALL
        SELECT  num + 1
        FROM    q
        WHERE num <= 26
        )
        SELECT CHAR(num + 65) FROM    q


SQL Wizardry Part Four - passing lists of data to SQL Server

Introduction 

Welcome to the fourth instalment of my series of articles on SQL. Today I intend to address an issue that I often see asked about in forums, that is, how to pass a list of values in to a stored proc and use it to select or insert data. We will look at three ways of doing this, and discuss the pros and cons of each.

Creating the tables

First, we’ll need some sample data. For this exercise, we’ll imagine a table that stores names and birthdays and has an id for a key. Here is the table SQL.

create table birthdays
(
  id int identity,
  firstName varchar(50),
  lastName varchar(50),
  birthday date
)
And here is the SQL to insert some values:
 
insert into birthdays values ('Fred', 'Smith', '1969/02/17'), ('Sarah', 'Smith', '1971/09/15'), ('Mary', 'Smith', '1996/07/20'),('Billy', 'Smith', '2000/07/01'), ('Sarah', 'Jones', '1945/12/26')

As you can see, just using SQL allows us to write one line to insert many values. More on that, later.
Now, the first thing we might want to do, is find people with the same surname or birthday, for example:

select * from birthdays where lastName = 'smith'
This is obviously easy to do with a parameter in a stored procedure. But what if we had a reason to select a group of values by id, which could be any length ? Here is the SQL: select * from birthdays where id in (1,3) But if you were to write a proc like this:

create proc findById1 @ids varchar(20)
as
begin

 select * from birthdays where id in (@ids)
 
end
That would create fine. Now do this:

findById1 '1,3'
 
Your error is: 


Msg 245, Level 16, State 1, Procedure findById1, Line 5
Conversion failed when converting the varchar value '1,3' to data type int.
SQL server cannot split your csv for you.  It is literally doing this:


Select * from birthdays where id = ‘1,3’


Which, of course, is not what we want.


Passing in a CSL

The most obvious thing to do, is to pass the value in and parse it.

CREATE proc findById2 (@list nvarchar(MAX))
AS
BEGIN

   DECLARE @pos        int,
           @nextpos    int,
           @valuelen   int

   SELECT @pos = 0, @nextpos = 1

   WHILE @nextpos > 0
   BEGIN
      SELECT @nextpos = charindex(',', @list, @pos + 1)
      SELECT @valuelen = CASE WHEN @nextpos > 0
                              THEN @nextpos
                              ELSE len(@list) + 1
                         END - @pos - 1

      select * from birthdays where id =  convert(int, substring(@list, @pos + 1, @valuelen)) 
      SELECT @pos = @nextpos
   END
END
And we can run it like this:
findById2 '1,3'
 
There’s a few issues here.  Not least is that you get a table for each 
row.  But the code itself sure is ugly.  Let’s get it all in to a temp 
table and see how it looks:


CREATE proc findById3 (@list nvarchar(MAX))
AS
BEGIN

declare @list nvarchar(MAX) = '1,3'

 create table #values
 (
    id int,
    birthday date,
    firstname nvarchar(50),
    lastname nvarchar(50)
 )

   DECLARE @pos        int,
           @nextpos    int,
           @valuelen   int

   SELECT @pos = 0, @nextpos = 1

   WHILE @nextpos > 0
   BEGIN
      SELECT @nextpos = charindex(',', @list, @pos + 1)
      SELECT @valuelen = CASE WHEN @nextpos > 0
                              THEN @nextpos
                              ELSE len(@list) + 1
                         END - @pos - 1
      insert into #values
      select id, birthday, firstname, lastname from birthdays where id =  convert(int, substring(@list, @pos + 1, @valuelen)) 
      SELECT @pos = @nextpos
   END
   
   select * from #values
   
END


And you run it like this:


findById3 '1,3'
 
Try changing the values in the list and see what happens.



So, this works, but it’s clearly pretty ugly.  We’re creating temp 
tables, stepping over strings, doing all sorts of nasty stuff.  This is 
not something I recommend you’d ever do.  I really included it to show 
you how NOT to do things, and to show a BAD alternative you might 
encounter ‘in the wild’.  My first port of call in situations like this,
 is to use XML.


XML processing

XML became a valid type for data in SQL Server 2005. Before that, a function called OpenXML was used to parse XML. If you see code that uses OpenXML and you’re not in SS2000, I recommend converting it. http://www.sommarskog.se/arrays-in-sql-2005.html#XML is a great read on the pros and cons of different ways to use XML. The short version is, it’s better to store your values as attributes, than as text in nodes. So, feel free to read that article, but, we’ll mostly be working with XML that uses attributes. The great advantage of using XML is, of course, that if your calls are coming from procedural code ( and they almost certainly are ), odds are you’re using a language that knows what XML is and offers all sorts of tools for building it. Even DataTables in .NET can be serialised to XML, as can any serializable class. So, now we are going to create a proc which takes this as an input:

Here is the proc:
create proc findByIdWithXml @xml xml
as
begin

;with fromXml as
(
SELECT Y.ID.value('(@val)[1]', 'int') as id
FROM @xml.nodes('/ids/id') as Y(ID)
)

select b.id, firstName, lastName, birthday from birthdays b inner join fromXml x on x.id = b.id;

end
Call it like this:
findByIdWithXml '<ids><id val="1"><id val="3" /></id></ids>' 
and it returns:
id firstName lastName birthday
1 Fred Smith 1969-02-17
3 Mary Smith 1996-07-20
Some things to note: we need to pass in the type of the object we want to pull out, as a string. If we were to select /ids in the nodes statement, we’d only get one node out, even though it has a many child id nodes, we’d only select one. @ before the name, means it’s an attribute. We use [1] because I’ve read that this makes the query faster, although in the real world, it’s superfluous ( it means, grab the first value in the group ). This is definitely much neater than using a csl. But, it’s also more powerful. Now we can define more than one way to get values out. Let’s try this:
create proc findWithXml @xml xml
as 
begin

;with fromXML as
(
SELECT 
Y.bday.value('(@id)[1]', 'int') as id,
Y.bday.value('(@fname)[1]', 'varchar(255)') as fname
FROM @xml.nodes('/birthdays/bday') as Y(bday)
)
select b.id, firstName, lastName, birthday from birthdays b inner join fromXml x on x.id = b.id or x.fname = b.firstName;

end
Now we’re allowing two different types of search, id and first name. Obviously, we could expand this as much as we wanted. The CTE returns this:
id fname
1 NULL
NULL Sarah
4 NULL
But this is fine, because NULL does not equal NULL in SQL. So even if there’s nulls in the source table ( which I allowed ), it would still not match on them.
findWithXml '<birthdays><bday id="1"><bday fname="Sarah"><bday id="4" /></birthdays>' 
returns this:
id firstName lastName birthday
1 Fred Smith 1969-02-17
2 Sarah Smith 1971-09-15
5 Sarah Jones 1945-12-26
4 Billy Smith 2000-07-01
Note that my use of the name ‘Sarah’ has confirmed that this will return multiple matches. Note also that I’ve not used ‘ORDER BY’ in my proc, so they are not in id order. Of course, this is easily resolved.

INSERTS with XML

Of course, now that we’ve moved to a strongly defined format, we can start to also use XML to do inserts ( of course, we could always do deletes, because we’d delete on only one value, same as we select ). The concept is the same across the board, use a CTE to create an in table memory, and then use it with our existing tables.
create proc insertWithXml @xml xml
as
begin

;with fromXML as
(
SELECT 
Y.bday.value('(@fname)[1]', 'varchar(255)') as fname,
Y.bday.value('(@lname)[1]', 'varchar(255)') as lname,
Y.bday.value('(@date)[1]', 'date') as bday
FROM @xml.nodes('/birthdays/bday') as Y(bday)
)

insert into birthdays (firstname, lastname, birthday)
select fname, lname, bday from fromXml;

end
Note that the column names don’t have to be the same, just in the same order.
insertWithXml '<birthdays><bday fname="Hannah" lname="Jones" date="1972/12/31"><bday fname="Calvin" lname="Kaputnik" date="1914/11/11" /></birthdays>' 
Now select all and see the result:
select * from birthdays
Two values have been inserted. Note that this is not as efficient as using a proper bulk insert process if you have TONS of records, but it’s great if you need to insert a small number at a time and want to call a proc once, instead of X times.

Table Value Parameters

Starting in SS2008, it is possible to pass in a table as a parameter. While our code above was quite compact, there was a separate step to turn XML in to a table, and although I’ve never had any issue with doing this, I am told there are quirks to watch out for. So, this seems better right ? There are a few gotchas to be aware of. First of all, TVPs inside a proc must be marked as read only ( which means you also can’t insert in to them or delete from them ). That seems reasonable. Secondly, TVPs require you to define them first. This means that if you have a proc that takes a TVP, you need to also install the TVP on your SQL Server instance for it to work, and you can easily end up with a DB full of TVPs, which strikes me as more confusing than just using one type that is natively supported. But the real issue that I can see is that, as far as I can tell, TVPs are not supported by entity framework. This is a real blow, if you could create a List of a class and pass it to a proc, that would be very powerful indeed. As it stands, it means that even if you don’t use EF, using TVPs closes the door on using EF for any other projects you need to write against your DB. I know I’ve often had to write small, single use apps, and having EF create my data layer for free has always been a very powerful reason to use it. With those caveats in mind, let’s press on.
CREATE TYPE BirthdayTableType AS TABLE 
( 
  id int,
  firstName varchar(50),
  lastName varchar(50),
  birthday date
);
GO
This creates the actual TVP type. As you can see, it’s a table declaration, with some small syntax changes. In fact, I copied and pasted the code for our table to create this, and just removed the identity specification ( it turns out this is valid, although it’s clearly largely useless ). And here is the proc:
CREATE PROCEDURE dbo.findWithTVP
    @TVP BirthdayTableType READONLY
    AS 
begin
    
    select * from birthdays b
    inner join @TVP t on t.id = b.id or t.birthday = b.birthday or t.firstname = b.firstname or t.lastname  = b.lastname
end
This is certainly even neater than the XML solution, and it’s a world away from the comma seperated list solution, both in usefulness and in readability. While we’re clearly not typically going to create TVPs in SQL, this bit is actually more painful.
DECLARE @tvp AS BirthdayTableType;
INSERT INTO @tvp (id, firstname, lastname, birthday) values(1, null, null, null)
INSERT INTO @tvp (id, firstname, lastname, birthday) values(null, null, 'kaputnik', null)
INSERT INTO @tvp (id, firstname, lastname, birthday) values(null, 'sarah', null, null)
INSERT INTO @tvp (id, firstname, lastname, birthday) values(null, null, null, '1996-07-20')

exec findWithTVP @tvp
And this will return the records we would expect. And, again, we can easily write insert code using a TVP, and, I believe that it’s possible in normal ( non-EF ) .NET code, to just pass a datatable through as a parameter. So, this would make for neat code with a traditional data layer, where the result of one proc needs to be passed to another proc.
  


 



 

Wednesday, 17 July 2013

Agile Methodology

Agile Methodology

What Is Agile?

Agile methodology is an alternative to traditional project management, typically used in software development. It helps teams respond to unpredictability through incremental, iterative work cadences, known as sprints. Agile methodologies are an alternative to waterfall, or traditional sequential development.

What is Scrum?

Scrum is the most popular way of introducing Agility due to its simplicity and flexibility. Because of this popularity, many organizations claim to be “doing Scrum” but aren’t doing anything close to Scrum’s actual definition. Scrum emphasizes empirical feedback, team self management, and striving to build properly tested product increments within short iterations. Doing Scrum as it’s actually defined usually comes into conflict with existing habits at established non-Agile organizations.
Scrum has only three roles: Product Owner, Team, and Scrum Master. These are described in detail by the Scrum Training Series. The responsibilities of the traditional project manager role are split up among these three Scrum roles. Scrum has five meetings: Backlog Grooming (aka Backlog Refinement), Sprint Planning, Daily Scrum (aka 15-minute standup), the Sprint Review Meeting, and the Sprint Retrospective Meeting.
Many books and classes are available from a variety of competing sources of varying accuracy and quality.  One place to start would be the Scrum Training Series, which uses an entertaining approach to cover the most popular way of introducing Agile to teams. You can also download the 6-page illustrated Scrum Reference Card.

Where Did Agile Come From?

In 1970, Dr. Winston Royce presented a paper entitled “Managing the Development of Large Software Systems,” which criticized sequential development. He asserted that software should not be developed like an automobile on an assembly line, in which each piece is added in sequential phases. In such sequential phases, every phase of the project must be completed before the next phase can begin. Dr. Royce recommended against the phase based approach in which developers first gather all of a project’s requirements, then complete all of its architecture and design, then write all of the code, and so on. Royce specifically objected to this approach due to the lack of communication between the specialized groups that complete each phase of work.
It’s easy to see how the “waterfall” methodology is far from optimized compared to agile methodology. First of all, it assumes that every requirement of the project can be identified before any design or coding occurs. Put another way, do you think you could tell a team of developers everything that needed to be in a piece of software before it was up and running? Or would it be easier to describe your vision to the team if you could react to functional software? Many software developers have learned the answer to that question the hard way: At the end of a project, a team might have built the software it was asked to build, but, in the time it took to create, business realities have changed so dramatically that the product is irrelevant. In that scenario, a company has spent time and money to create software that no one wants. Couldn’t it have been possible to ensure the end product would still be relevant before it was actually finished?

Why Agile?

Agile development methodology provides opportunities to assess the direction of a project throughout the development lifecycle. This is achieved through regular cadences of work, known as sprints or iterations, at the end of which teams must present a potentially shippable product increment. By focusing on the repetition of abbreviated work cycles as well as the functional product they yield, agile methodology is described as “iterative” and “incremental.” In waterfall, development teams only have one chance to get each aspect of a project right. In an agile paradigm, every aspect of development — requirements, design, etc. — is continually revisited throughout the lifecycle. When a team stops and re-evaluates the direction of a project every two weeks, there’s always time to steer it in another direction.
The results of this “inspect-and-adapt” approach to development greatly reduce both development costs and time to market. Because teams can develop software at the same time they’re gathering requirements, the phenomenon known as “analysis paralysis” is less likely to impede a team from making progress. And because a team’s work cycle is limited to two weeks, it gives stakeholders recurring opportunities to calibrate releases for success in the real world. Agile development methodology helps companies build the right product. Instead of committing to market a piece of software that hasn’t even been written yet, agile empowers teams to continuously replan their release to optimize its value throughout development, allowing them to be as competitive as possible in the marketplace. Development using an agile methodology preserves a product’s critical market relevance and ensures a team’s work doesn’t wind up on a shelf, never released.

Wednesday, 26 June 2013

Introduction to LINQ Queries (C#)

A query is an expression that retrieves data from a data source. Queries are usually expressed in a specialized query language. Different languages have been developed over time for the various types of data sources, for example SQL for relational databases and XQuery for XML. Therefore, developers have had to learn a new query language for each type of data source or data format that they must support. LINQ simplifies this situation by offering a consistent model for working with data across various kinds of data sources and formats. In a LINQ query, you are always working with objects. You use the same basic coding patterns to query and transform data in XML documents, SQL databases, ADO.NET Datasets, .NET collections, and any other format for which a LINQ provider is available.
All LINQ query operations consist of three distinct actions:
  1. Obtain the data source.
  2. Create the query.
  3. Execute the query.
The following example shows how the three parts of a query operation are expressed in source code. The example uses an integer array as a data source for convenience; however, the same concepts apply to other data sources also. This example is referred to throughout the rest of this topic.
class IntroToLINQ
{        
    static void Main()
    {
        // The Three Parts of a LINQ Query: 
        //  1. Data source. 
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

        // 2. Query creation. 
        // numQuery is an IEnumerable<int> 
        var numQuery =
            from num in numbers
            where (num % 2) == 0
            select num;

        // 3. Query execution. 
        foreach (int num in numQuery)
        {
            Console.Write("{0,1} ", num);
        }
    }
}
The following illustration shows the complete query operation. In LINQ the execution of the query is distinct from the query itself; in other words you have not retrieved any data just by creating a query variable.
Complete LINQ Query Operation
In the previous example, because the data source is an array, it implicitly supports the generic IEnumerable<T> interface. This fact means it can be queried with LINQ. A query is executed in a foreach statement, and foreach requires IEnumerable or IEnumerable<T>. Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T> are called queryable types.
A queryable type requires no modification or special treatment to serve as a LINQ data source. If the source data is not already in memory as a queryable type, the LINQ provider must represent it as such. For example, LINQ to XML loads an XML document into a queryable XElement type:
// Create a data source from an XML document. 
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");
With LINQ to SQL, you first create an object-relational mapping at design time either manually or by using the Object Relational Designer (O/R Designer). You write your queries against the objects, and at run-time LINQ to SQL handles the communication with the database. In the following example, Customers represents a specific table in the database, and the type of the query result, IQueryable<T>, derives from IEnumerable<T>.
Northwnd db = new Northwnd(@"c:\northwnd.mdf");

// Query for customers in London.
IQueryable<Customer> custQuery =
    from cust in db.Customers
    where cust.City == "London"
    select cust;
For more information about how to create specific types of data sources, see the documentation for the various LINQ providers. However, the basic rule is very simple: a LINQ data source is any object that supports the generic IEnumerable<T> interface, or an interface that inherits from it.
NoteNote
Types such as ArrayList that support the non-generic IEnumerable interface can also be used as a LINQ data source. For more information, see How to: Query an ArrayList with LINQ.
The query specifies what information to retrieve from the data source or sources. Optionally, a query also specifies how that information should be sorted, grouped, and shaped before it is returned. A query is stored in a query variable and initialized with a query expression. To make it easier to write queries, C# has introduced new query syntax.
The query in the previous example returns all the even numbers from the integer array. The query expression contains three clauses: from, where and select. (If you are familiar with SQL, you will have noticed that the ordering of the clauses is reversed from the order in SQL.) The from clause specifies the data source, the where clause applies the filter, and the select clause specifies the type of the returned elements. These and the other query clauses are discussed in detail in the LINQ Query Expressions (C# Programming Guide) section. For now, the important point is that in LINQ, the query variable itself takes no action and returns no data. It just stores the information that is required to produce the results when the query is executed at some later point. For more information about how queries are constructed behind the scenes, see Standard Query Operators Overview.
Note Note
Queries can also be expressed by using method syntax. For more information, see Query Syntax and Method Syntax in LINQ (C#).
As stated previously, the query variable itself only stores the query commands. The actual execution of the query is deferred until you iterate over the query variable in a foreach statement. This concept is referred to as deferred execution and is demonstrated in the following example:
//  Query execution.  
foreach (int num in numQuery)
{
    Console.Write("{0,1} ", num);
}
The foreach statement is also where the query results are retrieved. For example, in the previous query, the iteration variable num holds each value (one at a time) in the returned sequence.
Because the query variable itself never holds the query results, you can execute it as often as you like. For example, you may have a database that is being updated continually by a separate application. In your application, you could create one query that retrieves the latest data, and you could execute it repeatedly at some interval to retrieve different results every time.
Queries that perform aggregation functions over a range of source elements must first iterate over those elements. Examples of such queries are Count, Max, Average, and First. These execute without an explicit foreach statement because the query itself must use foreach in order to return a result. Note also that these types of queries return a single value, not an IEnumerable collection. The following query returns a count of the even numbers in the source array:
var evenNumQuery = 
    from num in numbers
    where (num % 2) == 0
    select num;

int evenNumCount = evenNumQuery.Count();
To force immediate execution of any query and cache its results, you can call the ToList<TSource> or ToArray<TSource> methods.
List<int> numQuery2 =
    (from num in numbers
     where (num % 2) == 0
     select num).ToList();

// or like this: 
// numQuery3 is still an int[] 

var numQuery3 =
    (from num in numbers
     where (num % 2) == 0
     select num).ToArray();
You can also force execution by putting the foreach loop immediately after the query expression. However, by calling ToList or ToArray you also cache all the data in a single collection object.

Tuesday, 25 June 2013

Getting started with CEBP

To get started, IT buyers need to do two things. The first is to start your UC deployment -- but do not choose a vendor based on who your VoIP or email vendor is. Instead, think of UC as a development platform, and choose your vendor based on its ability to integrate into your current application infrastructure and business processes.
The second task is to evaluate your business processes and understand which ones will benefit most from being communications-enabled. These are typically the ones with the highest amounts of human latency. Taking a platform approach, coupled with an understanding of the business process benefits, will create a higher likelihood of a successful deployment.

CEBP helps companies be more efficient

Communications-enabled business processes enable most companies to be much more agile than they have been before. Organizations can deliver critical information to anyone in the extended enterprise at any time, over any device in real time, ultimately saving companies huge amounts of time. For organizations that have adopted CEBP, many processes that previously took hours to complete can now be completed in minutes. CEBP allow organizations to make faster, more accurate decisions. This will lead to a more efficient workforce, higher productivity and even, in many cases, higher customer satisfaction.
Companies will vary in deciding which elements of UC to deploy and which processes to communications-enable. There is no company that should integrate all elements of UC into all processes, but most companies will integrate some of the elements. These are the elements of UC most likely to be used in a CEBP:
  • Presence -- This allows the process to understand which individuals are available and how to reach them. This is the main reason I feel presence is the key foundational element of UC, not VoIP.
  • Email and messaging -- This will be the most common method of delivering information to the key individuals.
  • Integration into a skills database, customer information or other data source -- An additional source of information can be used to refine the decision the CEBP makes.
  • Mobile extension -- This will allow information to be delivered to devices and users that are not tied to a desktop.
Other components such as voice, video, conferencing and chat will also be used to allow users to communicate with one another, but the use will be dictated by the process.