C# – Enumerable Methods

C# – LINQ Enumerable Methods

Link to Microsoft Docs: Here

Aggregate
– Iterates over the elements in a sequence and aggregates them using the specified aggregate function.
– Aggregate function takes in 2 arguments: seed and function
Sample Code
All
– Whether all elements in the collection match a certain predicate
– Returns Boolean result
– Returns true if and only if there is not an item in the list that fails to match the predicate condition
– Empty collection will return true
Sample Code
Any
– Determines any element in the sequence matches the predicate
– Returns Boolean result
– Parameters IEnumerable
– It uses early-exit once it meets its predicate

public static bool Any<TSource&gt(this IEnumerable<TSource&gt source) {
            if (source == null) throw Error.ArgumentNull("source");
            using (IEnumerator<TSource&gt e = source.GetEnumerator()) {
                if (e.MoveNext()) return true;
            }
            return false;
        }
public static bool Any<TSource&gt(this IEnumerable<TSource&gt source, Func<TSource, bool&gt predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return true;
            }
            return false;

}
Sample Code

Append
Refer to Concat method
AsEnumerable
– Generic interface which defines a template for looping, allows to cast a specific type. You can access it through queries or for-each loop.
– It helps to execute part of the query in memory.
Table.Where(predicate) => query executed at SQL Server level
Table.AsEnumerable().Where(predicate) => query executed in memory

Table.Where(somePredicate)
     .Select(someProjection)
     .AsEnumerable()
     .SomethingElse()

Reference
Sample Code

Average
– Calculates the average of the sequence of numeric values, returns single average result, it is an extension method.
Sample Code
Cast
– Attempts to cast each item in the collection. Only performs cast and not cast conversion For example cast conversion from object to long will throw InvalidCastException.
– You can cast to base class but not the opposite.
– Useful when converting IEnumerable to an IEnumerable <T>
Sample Code
Concat
– Concatenates two sequences.
– Two parameters of type IEnumerable and returns concatenated elements of the two inputs of type IEnumerable.
– Can combine Lists, Arrays or IEnumerables together.
– For adding List for performance it is better to use AddRange.
Sample Code
Contains
– Search for the specific element in the sequence.
– Parameters are source IEnumerable and value and returns boolean result.
– Terminated once the matched value is found.
– Extension method can be called on collections such as arrays, lists, etc.
– It has both extension and List method.
– Contains extension method can be called on any type that implements IEnumerable.
Sample Code
Count ?
– Returns the number of elements in a sequence.
– Takes IEnumerable as parameter and returns int in result.
– Not very useful as it always acts upon List and arrays when they have other properties such as count and length.
– Count() is only effective when used with LINQ query expression.
– Count can take argument such as Lambda expression, where count only elements that meets the condition
Sample Code
DefaultIfEmpty
– returns default value instead of error. Used to replace empty collection with a default value of singleton collection
– you can pass parameter or no parameter
– can only be used to handle empty collection
List list = new List();
var result = list.DefaultIfEmpty(); // will return 0
result = list.DefaultIfEmpty(1); // will return 1

Sample Code
Distinct
– Returns distinct elements from a sequence and removes all the duplicates.
– Parameter as IEnumerable and returns IEnumerable collection which can be iterated.
– Heap allocations occur when you invoke Distinct, for better performance you can use loops.
Sample Code
ElementAt ?
– Returns the element at a specified index in a sequence.
– Parameters IEnumerable and Int32 zero-based index.
– In many IEnumerable types, you cannot directly index a certain element.
– It is better to use indexer for string for better performance. eg string[99] rather than string.ElementAt(99).
– If a collection has indexer then don’t use ElementAt().
– Can be used for Queue or Stack but it is not a best practice instead try to convert stacks and queue into array or list and use the indexer.
Sample Code
ElementAtOrDefault
– Returns the element at a specified index in a sequence or a default value if the index is out of range.
– It handles out-of-range access without throwing an exception.
– Parameters IEnumerable and Int32 zero-based index.
– Returns element at the specified position or default value.
Sample Code
Empty
– Returns an empty IEnumerable(Of T) that has the specified type argument.
– When you want to create an empty sequence.
– Type of the sequence declaration is important.
– It has performance advantage because it caches zero element array compared to empty array initialization.
Sample Code
Except
– Returns a difference from the two sequences, basically subtracts elements from the collection.
– The elements of second sequence is subtracted from the first sequence.
– Elements found in second sequence not available in first will be ignored.
Sample Code
First
– Returns the first matching object from the sequence if predicate is used or first item from the object.
– Parameter takes in as IEnumerable collection.
– Throws exception if not result found or empty collection
Sample Code
FirstOrDefault
– Returns either first element of a sequence or first element of the sequence that satisfies a condition, or a default value if the sequence contains no elements.
Sample Code
GroupBy
– Transforms the sequence into groups where each group has a key.
– For performance optimization it is better to use ToDictionary if it is used randomly.
– Also List can be used if it contains multiple elements (Dictinary of Lists).
Sample Code
GroupJoin
– Correlates the elements of two sequences based on key equality, and groups the results.
– It requires 4 arguements: secondary collection, function returns key from first object, function return key from 2nd object and last one that stores group data.
– Alternative solution will be to use Dictionary and implementing IEqualityComparer.
Sample Code
Intersect
– Returns a set of common results found from both collections.
Sample code
Join
– Matches every element in two sequences based on matching keys.
– Parameters: first sequence to join as outer parameter, then inner params – sequence to join the first sequence, outer sequence key to join each element, key for the second sequence and function to create the result from the matching result.
Sample Code
Last
– Returns the last element from the sequence to that matches the predicate in the sequence.
– Parameter – it takes sequence as the parameter and returns the last element from the sequence or last element that matches the condition.
Sample Code
LastOrDefault
– It returns the last element in the sequence or the default value.
– It also returns the last element of the sequence that matches a condition or default value. Parameter – it takes sequence as the parameter and returns the last element from the sequence or last element that matches the condition otherwise default value.
Sample Code
LongCount
– Returns an Int64 that represents the total number of elements in a collection.
– Use this method rather than Count when you expect the result to be greater than MaxValue.
– Also returns an Int64 that represents how many elements in a sequence match a condition.
Sample Code
Max
– Loops through the sequence and returns the highest value.
– The max 22 overload with different data-types Decimal, Double, Int32, Int64 and Single, and nullable versions of each of these.
– These methods are most useful with a lambda expression. Cannot be called on empty collection throws an exception.
Sample Code
Min
– Loops through the sequence and returns the smalled value.
– The max 22 overload with different data-types Decimal, Double, Int32, Int64 and Single, and nullable versions of each of these.
– These methods are most useful with a lambda expression. Cannot be called on empty collection throws an exception.
Sample Code
OfType
– Gets all the elements by their matching type in the collection (IEnumerable).
– It provides a useful way to query for elements of a certain type.
Sample Code
OrderBy
– Identifies how the sequence should be arranged.
– It can be invoked to any sequence that implements IEnumerable.
– It is better to use OrderBy when compared with generic Sort function.
– Parameter IEnumerable collection and function to extract key from collection and IComparer to compare keys.
Sample Code
OrderByDescending
– Sorts the element in the collection from higest to lowest.
– It uses the lambda expression to select the key for sorting.
– Sorts the elements of a sequence in ascending/descending order by using a specified comparer.
Sample Code
Prepend
– use Concat instead, not enough information provided here.
Range
– Takes the parameter as start and count and then it generates the sequence on integral numbers in progressing order within a specified range.
– The second argument needs to be greater than zero, will throw exception if it is negative.
Sample Code
Repeat
– Takes in the parameter as element and count – repeated number of times and then it generates a sequence that contains one repeated value.
– IEnumerable result can be converted into ToArray() or ToList() to assign array or list.
Sample Code
Reverse
– Inverts the order of the elements in a collection (opposite), can be used with many collection types such as lists, array, IEnumerable.
– As for performance it is not the best practice, alternative approach is to use array.reverse or use loops.
– It is shortcut to use but not so good in performance.
Sample Code
Select
1) Modify each element in a collection into a new form
2) Modify each element into a new form by incorporating the element’s index.
– It can be applied on different collection types such as List.
Sample Code
SelectMany
1) Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.
2) Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.
3) Projects each element of a sequence to an IEnumerable, and flattens the resulting sequences into one sequence. The index of each source element is used in the projected form of that element.
4) Projects each element of a sequence to an IEnumerable, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein.
5) Projects each element of a sequence to an IEnumerable, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein. The index of each source element is used in the intermediate projected form of that element.
– Can change the element into an array or collection.
Sample Code
SequenceEqual
1) Determines whether two collections are equal by comparing the elements by using the default equality comparer for their type.
2) Determines whether two collections are equal by comparing their elements by using a specified IEqualityComparer.
– Testing two collections for equality.
– If using arrays consider using ArraysEquals for performance optimization.
Sample Code
Single
1) Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence.
2) Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists.
– Best used as runtime assert to throw errors.
Sample Code
SingleOrDefault
1) Returns the only element of a sequence, or a default value if the sequence is empty. This method throws an exception if there is more than one element in the sequence.
2) Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists. This method throws an exception if more than one element satisfies the condition.

var parentClaim = bl.Get(childClaimId: claimId)
                    .SingleOrDefault(x => x.ClaimRelationshipTypeId == reversalTypeId || x.ClaimRelationshipTypeId == reissueTypeId);

Sample Code

Skip
– Disregards the specified number of elements in the sequence and returns the remaining.
– No result will be visible unless you iterate using loop to view the collection data.
– You can use Take with Skip.
Sample Code
SkipLast
– Not enough information
SkipWhile
– Disregards the elements in the collection as long as predicate is true and returns the remaining elements in the collection.
– You will need to specify a predicate condition inorder to skip values.
– You can convert into ToArray to ToList to convert the IEnumerable back into an array or List.
Sample Code
Sum
– Calculates the sum of a collection of numeric values.
– There are 20 overloads for the data-types Decimal, Double, Int32, Int64 and Single, and nullable versions of each of these.
Sample Code
Take
– Returns the specified first several number of elements from the collection.
– Returns another collection of result.
– Receives parameter as element count.
– If parameter count exceeds with the number of elements in a collection, take will handle without any problem.
– You can use Take with Skip
Sample Code
TakeLast
– Not enough information, consider reversing the list and use take() method.
TakeWhile
– Returns the elements in the sequence while it matches the predicate.
– It precedes from the beginning of the collection.
Sample Code
ThenBy
– Orders the collection in ascending order
Sample Code
ThenByDescending
– Orders the collection in descending order
Sample Code
ToArray
– Converts collections into Arrays specially IEnumerable types.
– Reduces complexity and program length
– You can append the ToArray method to the query to obtain a cached copy of the query results.
Sample Code
ToDictionary
– Converts a sequence into a Dictionary.
– Applicable to IEnumerable collections such as arrays and Lists.
– It can optimize performance rather then using generic collections.
– Parameter: first set each key and second set each value.
Sample Code
ToHashSet
– Not enough information
ToList
– Creates a List from a set of collections with List constructor.
Sample Code
ToLookup
– Returns ILookup that allows indexing and iteration.
– It allows one key to be associated with multiple values.
Sample Code
Union
– Produces a new set of collections from joining 2 sets of collections.
– It removes duplicates to the collection
– The two collections needs to be same type
– Mostly works on Lists and Arrays
– Results are not sorted in union
– Alternative method could be hash table or dictionary but will not remove duplicates
Sample Code
Where
– Filters values based on the predicates and returns all the matched results
– Mostly used in queries
var results = bl.Get(parentClaimId: claimId)
.Where(x => x.ClaimRelationshipTypeId == reversalTypeId || x.ClaimRelationshipTypeId == reissueTypeId);

Sample Code
Zip
– Uses two collections and processes each element from both collections together.
– Zip will not throw an exception if the two collections are of unequal length.
Sample Code

Finally completed learning with LINQ Enumerable methods. My learning resource and examples are based from msdn, dreamincode and dotnetpearl. Thanks for the awesome articles.

Feel free to contact me if you have any concerns.

Live as if you were to die tomorrow. Learn as if you were to live forever..
-Mahatma Gandhi

C# – Framework Design Guidelines

BEST PRACTICE

Returns
1. NULL Returns
– When returning a collection or enumerable ALWAYS return an empty enumerable/collection

String
1. String Concatenation
– Use StringBuilder instead of String concatenation
– string concatenation creates new memory allocation for new string
– stringBuilder uses the same memory
2. Always use string.IsNullOrEmpty() and string.IsNullOrWhiteSpace() whenever possible

LINQ
1. WHERE() with FIRST()
– Avoid using WHERE and First together or First when you are unsure that the result can be null.
– Use FirstOrDefault() where ever possible

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {       
            //INCORRECT
            List numbers = new List{1,4,5,8,11,14,20,21,25,34,40};
            int firstEven = numbers.Where(x => x % 2 == 0).First();
            Console.WriteLine("First Even number : {0}", firstEven);
            
            //CORRECT
            int firstEvenCorrect = numbers.FirstOrDefault(x => x % 2 == 0);
            Console.WriteLine("First Even number : {0}", firstEvenCorrect);
        }
    }
}

Casting
1. Cast by “as (T)” instead of “(T)”

As (T) (T)
Returns null when casting is not possible Prefix casting will throw exception
Can be applied to reference type variable only Prefix is free for all
Cannot perform user-defined conversions Prefix can perform User defined conversion
//INCORRECT
var dog = (Dog)animal;

//CORRECT
var dog = animal as Dog;

Exceptions
1. Re-throwing exceptions

//INCORRECT 
throw ex;

//CORRECT
throw;

Enumerations
1. Use FOR LOOP for non collection eg array
2. Use FOR EACH for collection
3. Do not use OrderBy before Where clause

Keywords
1. Avoid using “ref” and “out” keywords as much as possible

Class
1. Always use properties instead of public variables

Sago

Sago

Names: Sago, sago palm, sago pearls
Hindi: Sabudana

sago palm tree
sago palm tree

What is Sago?
Sago is produced from sago palm, it is the starch extracted from the center of sago palm stems, then processed into small, circular pellets referred to as pearls.

For Vegan:
– Good source of protein.

Glycemic Index
– High GI food: recommended to take in low amount if you are a diabetic.

How is Sago Used?
– Sago is popular in Indian recipes
– Included in tea popular in Asian drink
– Included in desserts and breads
– Can combined with rice for light and low calorie meal
– Thickening foods such as gravy or sauces
– Powder form for flour substitue

- Sago is high in carbohydrate content.
- A 100-gram serving contains nearly 86 grams of carbs.

- 100 grams of sago contains less than 1/2 gram of protein

- Sago contains a very low amount of total and saturated fat.
- A 100-gram serving has only .2 gram of total fat and .1 gram of saturated

- Not a low calorie food
- A 100-gram serving of sago yields for 350 calories

- A 100-gram serving gives you 7 percent of your daily allowance.
- Contains small amounts of calcium, copper, potassium and sodium.

Health benefits:

1. Aid in digestion

2. Nutritional value: a source of pure carbohydrates with very little protein, vitamin C, calcium and minerals.

3. A high energy booster:
– Energy-boosting ingredients in soups, puddings, smoothies, side dishes and main courses. It is a good substitute for energy supplements.

4. You can gain weight quickly by eating sago.

5. Enhance joints and bone health
– It helps to improves the joints and bones because it has minerals like calcium, iron, etc. Sago has Glucosamine which boosts the bone density, flexibility and joint movements. It also increases the amount of synovial fluid which is responsible smooth movement of joints.

6. Controls Hypertension
– 100g of sago contains around 5mg of potassium. Potassium helps to improve blood circulation and one of the best to cure hyperternsion. It stimulates healthy blood flow which decreases the strain on cardiovascular system

7. Helps in Muscle growth
– Sago has a good source of protein which aid in growth of muscles and strengthening. Also helps in faster recovery of function cells.

sago_pearl
Sago Pearl

Lifestyle 01: Glycemic Index

Lifestyle 01: Glycemic Index

So I am beginning my first article with Glycemic Index, I was not aware with this term before but now I have enough information to share.

Photo by Dan Gold on Unsplash
Photo by Dan Gold on Unsplash

What is Glycemic Index?
Glycemic Index measures the carbohydrate-rich foods by the amount they elevate blood glucose levels compared to a standard food.

Glycemic index measures the carbohydrate-rich foods on a scale from 0 to 100 according to the extent to which they raise blood sugar levels.

Why it is important?
Foods with a low Glycemic Index digest more slowly and release sugar gradually into the bloodstream, keeping blood sugar stable.

Foods with a high Glycemic Index are those which are rapidly digested, absorbed and metabolised and results in high fluctuations in blood sugar (glucose) levels.

Monitoring your GI is one of the key secrets to long-term healthy life, reducing the risk of type 2 diabetes and heart disease. It is also one of the keys to maintaining weight loss.

It may also help to control your cholesterol level and appetite.

Note:
It is healthy to choose low GI foods but avoid over eating. IT IS PART OF HEALTHY EATING.

For a healthy lifestyle you also have to :
• Eat regularly
• Choose food from all groups
• Control sugar and sweets
• Reduce the amount of fat you eat
• Include foods high in fibre
• Limiting salt

Best practice to check your glucose before and 2 hours after a meal is the best way to know how your body handles the meal.

Please feel free to contact me if you like to share more information

Web Development Resource

Web Development Resource

Web Performance Link
Performance Monitoring Solution Link
Bootflat Flat UI color picker Link
Free library of website, e-commerce and marketing resources Link
Security, WordPress, email, fix, plugins, wordpress, plugins, themes, design, dev, development, security, htaccess, apache, php, sql, html, css, jquery, javascript, tutorials Link
A curated directory of resources & tools to help you build your Startup Link
Website Grader is a free online tool that grades your site against key metrics like performance, mobile readiness, SEO, and security Link

Temporary Tables

Temporary Tables/Variables
Temporary tables are created in tempdb database. They function like regular tables where you can perform Data Modification Language (DML) queries. If you create temp table inside stored procedure it gets destroyed once the stored procedure is completed. Scope of the temporary table is important, visible only to the particular user. Temporary tables begin with a pound symbol ‘#’ or ‘@’. Temporary tables can be indexed and DDL constraints can be applied.

There are multiple types of temporary tables:
1. Local temporary tables
2. Global temporary tables
3. Table Variable
4. Tempdb permanent tables
5. Global table variable

1. Local Temporary table
– Local temporary tables are only available in the current executing scope or the current connection to an instance of SQL Server
– Deleted after disconnects from SQL Server instance
– Cannot be shared between multiple users

CREATE TABLE #tmp

2. Global Temporary table
– Available in other sessions and any connection after created
– Deleted when all users that are referencing the table disconnected from the instance of SQL Server
– Can be shared between multiple users
– Once global temporary tables are created it is saved in the tempdb database

CREATE TABLE ##tmp

3. Table Variable
– Only visible to the connection that creates it, stored in RAM and delete after the batch or stored procedure is completed
– Table variable is prefixed with an ‘@’ sign
– Cannot have non-clustered indexes
– No constraints , default or statistics values for table variables

DECLARE @tmp TABLE

4. Tempdb tables
– Are visible to everyone and are deleted when the server is restarted

USE tempdb CREATE TABLE tmp

5. Global table variable

DECLARE @@tmp TABLE

Using sp_executesql
-sp_executesql runs under a different scope, so if you execute and add data to temp table you will not be able to access the temp table

EXECUTE sp_executesql N'SELECT name INTO #test'

You will not be able to run the select statement into #test temp table like:

SELECT * FROM #test

Analysis:
– When you breakup a complex query to multiple statements, it is better to use temp table for optimization reasons.
– Temporary tables are preferred over table variables interms of indexing and statistics and lifespan.
– For table variable entire block of code needs to be run whereas for temporary tables you can run temporary table anytime after it is created in the current session

CREATE TABLE #Temp
(
 id int NOT NULL,
 Name varchar (10)
)

INSERT INTO #Temp (id, Name)
VALUES (1,'Test')

SELECT * FROM #temp

You can run this statements seperately and #temp table will run

DECLARE @Temp TABLE
(
 id int NOT NULL,
 Name varchar (10)                                   
)

INSERT INTO @Temp (id, Name)
VALUES (1,'Test')

SELECT * FROM @temp

You will have to run the entire code together to get the results. The table variable lifespan is only for the duraton of the transaction that it runs.

Table variable is useful when you want to return table result from the user-defined function.
eg

CREATE FUNCTION claimsbyCode (@code int)
RETURNS
   @claimsbyCode TABLE (
    [id] [INT],
    [name] [varchar(20)]
   )
....

Working with Temp tables
Two methods to add data to temp table:
1. INSERT INTO temp table
2. SELECT INTO temp table

INSERT INTO temp table
– table needs to be created first and then it allows data to be inserted.
– will reuse data pages which are created in cache for DML operations
– will truncate the table when temp table is dropped


INSERT INTO #temptable
SELECT * FROM physicaltable

SELECT INTO temp table
– create the new table for you based on your select statement and inserts the resulting row from the query.
– creates new pages for table creation and physically remove them when the table is dropped.

SELECT * 
INTO #temptable
FROM physicaltablename
WHERE statement

In terms of performance, SELECT…INTO is much faster when compared with INSERT INTO

Happy days….

MS SQL SERVER – Triggers

MS SQL SERVER – Triggers

Today I was working on Triggers for one of my project so thought to share some information about triggers.

What are Triggers?
Trigger is a database object that is attached to a table and gets fired upon action. The actions are INSERT, UPDATE or DELETE.

How to perform an INSERT/UPDATE Trigger
In my case I had two separate tables: claims and claim status history. So when the claim status changes during the claim process then I wanted to store the history process. When a new claim is created there is a INSERT trigger to add a record to claim history table.

CREATE TRIGGER trg_xxx_update
ON [xxx].[xTable]
AFTER INSERT, UPDATE
AS
INSERT INTO [xxx].StatusHistory
(
  [Id],
  [StatusId],
  [CreatedDateTime],
  [CreatedBy],
  [UpdatedDateTime],
  [UpdatedBy]
)
SELECT
  Id,
  StatusId,
  UpdatedDateTime as CreatedDateTime,
  UpdatedBy as CreatedBy,
  UpdatedDateTime,
  UpdatedBy
FROM
  Inserted 

Action Definitions
1. INSERT – perform action after inserting a record to the table
2. UPDATE – perform action after an update is made to the table
3. DELETE – perform action when delete a record from the table

SQL SERVER supports 2 kinds of Triggers
– Data manipulation events (DML triggers) – INSERT/UPDATE/DELETE
– Data definition events (DDL triggers) such as CREATE TABLE

There are two kinds of DML triggers:
1. AFTER
– the trigger fires after the event it is associated with finishes and can only be defined on permanent talbles.
2. INSTEAD OF
– the trigger fires instead of the event it is associated with and can be defined on permanent tables and views

How trigger works
Trigger executes only once no matter how many rows it may affect and also the schema of the trigger must be same of the table or view.
Triggers make use of two special tables called inserted and deleted.
The inserted table contains the data referenced in an INSERT before it is actually comitted to the database.
The deleted table contains the data in the underlying table referenced in a DELETE before it is actually removed form the database
When using UPDATE both tables are used as new data referenced is contained in the inserted and the data that is updated is contained in deleted.

Nested After Triggers
Triggers can be nested that is trigger on TableA updates Table B then TableB trigger updates TableC and so on can continue to a maximum of 32 executions.
Nested triggers are on be default on SQL SERVER but you have the option to disable it.
To check the setting:

EXEC sp_configure 'nested triggers';

To stop all nested triggers:

EXEC sp_CONFIGURE 'nested_triggers',0
GO
RECONFIGURE
GO

RECONFIGURE is important to make the setting take place.

Stop trigger for a database:

ALTER DATABASE databasename
SET RECURSIVE_TRIGGERS ON | OFF

Restrict Trigger Nesting
This will stop the trigger recursion after certain levels. In following case it will stop after 5 recursion.

IF ((
SELECT TRIGGER_NESTLEVEL()) > 5 )
RETURN

Printing Trigger levels, ids

Print 'testing TRIGGER_NESTLEVEL '
+ CAST(TRIGGER_NESTLEVEL() AS VARCHAR(3))
;
print object_id( '[xxx].[trg_xxx_update]' );
print db_id();


INSTEAD OF Triggers

INSTEAD OF Triggers are common with views, the reason is that when you want to UPDATE a view only the base table can be updated at a time. Views may contain aggregations or functions which prevent update therefore An INSTEAD OF trigger can take that UPDATE statement against the view and instead of executing it, replace it with two or more UPDATE statements against the base tables of the view.

How to prevent trigger from recursing
1. Disable trigger recursion
2. Use a trigger INSTEAD OF UPDATE, INSERT
3. Control the trigger by preventing using IF UPDATE

ALTER TRIGGER [dbo].[tblXXX] 
   ON  [dbo].[tblXXX]
   FOR INSERT, UPDATE
AS 
BEGIN
    SET NOCOUNT ON

    IF UPDATE(Name) BEGIN
        UPDATE tblXXX 
        SET Name = Name + CAST((b.Id) AS VARCHAR(10))
        FROM tblXXX a
            INNER JOIN INSERTED b on a.Id = b.Id
    END
END

Side Effect
ROLLBACK TRAN – read more on this