LINQ TO OBJECT
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
//Create a list of Employees and Departments
IList<Department> departmentList = new List<Department>()
{new Department(100, "DotNet Lead"), new Department(101, "DotNet Developer"), new Department(200, "QA Lead"),
new Department(201, "QA Tester"), new Department(300, "UI Developer"), };
IList<Employee> employeeList = new List<Employee>()
{new Employee(1, "Anirban", 1000, 100), new Employee(2, "Sayantan", 830, 101), new Employee(3, "Biswajit", 500, 101), new Employee(4, "Prakriti", 500, 101),
new Employee(5, "Subhom", 800, 300), new Employee(6, "Avilash", 650, 200), };
SimpleOperations(departmentList,employeeList);
SimpleOperationsLambda(departmentList,employeeList);
}
private static void SimpleOperations(IList<Department> departmentList, IList<Employee> employeeList)
{
Console.WriteLine("Inside SimpleOperations" + Environment.NewLine);
//Using where clause
var filteredResult = from item in employeeList
where item.Salary > 800 && item.Salary < 1000
select item.Name;
foreach(string name in filteredResult)
Console.WriteLine(name);
Console.WriteLine("==============");
string[] empNames = (from item in employeeList
where item.Salary > 800 && item.Salary < 1000
select item.Name).ToArray();
foreach(string name in empNames)
Console.WriteLine(name);
Console.WriteLine("==============");
//calling a function from a where clause
List<Employee> resultList = (from item in employeeList
where IsDeveloper(item)
select item).ToList();
foreach(Employee emp in resultList)
Console.WriteLine(emp.Id + "," + emp.Name);
Console.WriteLine("==============");
//using multiple where clause
filteredResult = from item in employeeList
where !IsDeveloper(item)
|| item.Salary > 700
select item.Name;
foreach(string name in filteredResult)
Console.WriteLine(name);
Console.WriteLine("==============");
filteredResult = from s in employeeList
where !IsDeveloper(s)
where s.Salary > 800
select s.Name;
foreach(string name in filteredResult)
Console.WriteLine(name);
Console.WriteLine("==============");
}
private static void SimpleOperationsLambda(IList<Department> departmentList, IList<Employee> employeeList)
{
Console.WriteLine("Inside SimpleOperationsLambda" + Environment.NewLine);
//Using where clause
var filteredResult = employeeList.Where(i => i.Salary > 800 && i.Salary < 1000 ).Select(s => s.Name);
foreach(string name in filteredResult)
Console.WriteLine(name);
Console.WriteLine("==============");
//calling a function from a where clause
List<string> resultList = employeeList.Where(i => IsDeveloper(i) ).Select(s => s.Name).ToList();
foreach(string name in resultList)
Console.WriteLine(name);
Console.WriteLine("==============");
//using multiple where clause
filteredResult = employeeList.Where(i => !IsDeveloper(i) && i.Salary > 700 ).Select(s => s.Name);
foreach(string name in filteredResult)
Console.WriteLine(name);
Console.WriteLine("==============");
filteredResult = employeeList.Where(i => !IsDeveloper(i)).Where(i => i.Salary > 700 ).Select(s => s.Name);
foreach(string name in filteredResult)
Console.WriteLine(name);
Console.WriteLine("==============");
}
private static bool IsDeveloper(Employee emp)
{
return emp.DeptId == 101 ? true : false;
}
public class Employee
{
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
public int Salary
{
get;
set;
}
public int DeptId
{
get;
set;
}
public Employee(int id, string name, int salary, int deptId)
{
this.Id = id;
this.Name = name;
this.Salary = salary;
this.DeptId = deptId;
}
}
public class Department
{
public int DeptId
{
get;
set;
}
public string DeptName
{
get;
set;
}
public Department(int deptId, string deptName)
{
this.DeptId = deptId;
this.DeptName = deptName;
}
}
Example 2
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
//Create a list of Employees and Departments
IList<Department> departmentList = new List<Department>()
{new Department(100, "DotNet Lead"), new Department(101, "DotNet Developer"), new Department(200, "QA Lead"),
new Department(201, "QA Tester"), new Department(300, "UI Developer"), };
IList<Employee> employeeList = new List<Employee>()
{new Employee(1, "Anirban", 1000, 100), new Employee(2, "Sayantan", 830, 101), new Employee(3, "Biswajit", 500, 101), new Employee(4, "Prakriti", 500, 101),
new Employee(5, "Subham", 800, 200), new Employee(6, "Avilash", 650, 300), };
SimpleOperations(departmentList,employeeList);
}
private static void SimpleOperations(IList<Department> departmentList, IList<Employee> employeeList)
{
Console.WriteLine("Inside SimpleOperations" + Environment.NewLine);
//Using OrderBy clause
List<Employee> empList = (from s in employeeList
where s.Salary > 600
orderby s.DeptId descending
select s).ToList();
foreach(Employee emp in empList)
Console.WriteLine(emp.DeptId + ", " + emp.Name);
Console.WriteLine("=====================");
Console.WriteLine("====LAMDA EXPRESSION===");
//OrderBy Clause using Lamda Expression
List<Employee> empListResult = employeeList.Where(i=>i.Salary > 600).OrderByDescending(i=>i.DeptId).Select(s=>s).ToList();
foreach(Employee emp in empListResult)
Console.WriteLine(emp.DeptId + ", " + emp.Name);
Console.WriteLine("=====================");
//Using OrderBy clause
empList = (from s in employeeList
where s.DeptId == 100 || s.DeptId == 101
orderby s.DeptId descending, s.Name
select s).ToList();
foreach(Employee emp in empList)
Console.WriteLine(emp.DeptId + ", " + emp.Name);
Console.WriteLine("=====================");
Console.WriteLine("====LAMDA EXPRESSION===");
empListResult = employeeList.Where(i=>i.DeptId == 100||i.DeptId == 101).OrderByDescending(i=>i.DeptId).ThenBy(i=>i.Name).Select(s=>s).ToList();
foreach(Employee emp in empListResult)
Console.WriteLine(emp.DeptId + ", " + emp.Name);
Console.WriteLine("=====================");
//Using GroupBy clause
Dictionary<int,List<Employee>> result = (from item in employeeList
where item.DeptId == 100 || item.DeptId == 101
orderby item.DeptId descending
group item by item.DeptId).ToDictionary(s => s.Key, s => s.ToList());
foreach(KeyValuePair<int,List<Employee>> entry in result)
{
Console.WriteLine(entry.Key);
foreach(Employee emp in entry.Value.ToList())
Console.WriteLine(emp.Name);
}
Console.WriteLine("=====================");
Console.WriteLine("====LAMDA EXPRESSION===");
Dictionary<int,List<Employee>> empresult = employeeList.Where(i=>i.DeptId == 100 || i.DeptId == 101).OrderByDescending(i=>i.DeptId).GroupBy(i=>i.DeptId).ToDictionary(s => s.Key, s => s.ToList());
foreach(KeyValuePair<int,List<Employee>> entry in empresult)
{
Console.WriteLine(entry.Key);
foreach(Employee emp in entry.Value.ToList())
Console.WriteLine(emp.Name);
}
Console.WriteLine("=====================");
//Using GroupBy clause
Dictionary<int,int> result2 = (from item in employeeList
where item.DeptId == 100 || item.DeptId == 101
orderby item.DeptId descending
group item by item.DeptId).ToDictionary(s => s.Key, s => s.Count());
foreach(KeyValuePair<int,int> entry in result2)
{
Console.WriteLine(entry.Key + ", " + entry.Value);
}
Console.WriteLine("=====================");
Console.WriteLine("====LAMDA EXPRESSION===");
Dictionary<int,int> empresult2 = employeeList.Where(i=>i.DeptId==100 || i.DeptId ==101).OrderByDescending(i=>i.DeptId).GroupBy(i=>i.DeptId).ToDictionary(s => s.Key, s => s.Count());
foreach(KeyValuePair<int,int> entry in empresult2)
{
Console.WriteLine(entry.Key + ", " + entry.Value);
}
Console.WriteLine("=====================");
//Using ANY and ALL clause
bool isTrue = (from s in employeeList
select s).All( s => s.Name.Contains("s"));
Console.WriteLine("All of the Employee Name contains s: " + isTrue);
isTrue = (from s in employeeList
select s).All( s => s.Name.Contains("a"));
Console.WriteLine("All of the Employee Name contains a: " + isTrue);
isTrue = (from s in employeeList
select s).Any( s => s.Name.ToLower().Contains("p"));
Console.WriteLine("Any of the Employee Name contains p: " + isTrue);
Console.WriteLine("=====================");
Console.WriteLine("====LAMDA EXPRESSION===");
bool istrue = employeeList.All(i => i.Name.Contains("s"));
Console.WriteLine("All of the Employee Name contains s: " + istrue);
istrue = employeeList.All(i => i.Name.Contains("a"));
Console.WriteLine("All of the Employee Name contains a: " + istrue);
istrue = employeeList.Any(i => i.Name.ToLower().Contains("a"));
Console.WriteLine("Any of the Employee Name contains p: " + isTrue);
}
}
Example 3
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
//Create a list of Employees and Departments
IList<Department> departmentList = new List<Department>()
{new Department(100, "DotNet Lead"), new Department(101, "DotNet Developer"), new Department(200, "QA Lead"),
new Department(201, "QA Tester"), new Department(300, "UI Developer"), };
IList<Employee> employeeList = new List<Employee>()
{new Employee(1, "Anirban", 1000, 100), new Employee(2, "Sayantan", 830, 101), new Employee(3, "Biswajit", 500, 101), new Employee(4, "Prakriti", 500, 101),
new Employee(5, "Subhom", 800, 300), new Employee(6, "Avilash", 650, 200), };
JoinOperations(departmentList,employeeList);
}
private static void JoinOperations(IList<Department> departmentList, IList<Employee> employeeList)
{
//Inner join clause
var innerjoin = from emp in employeeList //outer sequence
join dept in departmentList //inner sequence
on emp.DeptId equals dept.DeptId
select new { DDepartmentId = dept.DeptId,
DDepartmentName = dept.DeptName,
EDepartmentId = emp.DeptId,
EName = emp.Name };
foreach(var details in innerjoin)
{
Console.WriteLine("DDepartmentId: " + details.DDepartmentId);
Console.WriteLine("DDepartmentName: " + details.DDepartmentName);
Console.WriteLine("EDepartmentId: " + details.EDepartmentId);
Console.WriteLine("EName: " + details.EName);
}
Console.WriteLine("=======================");
//Group join
var groupjoin = from dept in departmentList //outer sequence
join emp in
(from einner in employeeList//inner sequence
where einner.Salary > 700
select einner)
on dept.DeptId equals emp.DeptId
into empGroup
select new { DDepartmentId = dept.DeptId,
DDepartmentName = dept.DeptName,
GEmployee = empGroup};
foreach(var details in groupjoin)
{
Console.WriteLine("DDepartmentId: " + details.DDepartmentId);
Console.WriteLine("DDepartmentName: " + details.DDepartmentName);
foreach(var groupEmp in details.GEmployee)
{
Console.WriteLine("EDepartmentId: " + groupEmp.DeptId);
Console.WriteLine("EName: " + groupEmp.Name);
}
}
Console.WriteLine("=======================");
//Outer Join
var outerjoin = from dept in
(from deptinner in departmentList //outer sequence
where deptinner.DeptName.ToLower().Contains("developer")
|| deptinner.DeptName.ToLower().Contains("tester")
select deptinner)
join emp in
(from einner in employeeList//inner sequence
where einner.Salary > 700
select einner)
on dept.DeptId equals emp.DeptId
into empGroup
//from eg in empGroup
from eg in empGroup.DefaultIfEmpty()
orderby dept.DeptName descending
//orderby eg.name
select new { DDepartmentId = dept.DeptId,
DDepartmentName = dept.DeptName,
GEmployeeName = eg!=null ? eg.Name : "n/a",
GEmployeeSalary = eg!=null ? eg.Salary : 0};
foreach(var details in outerjoin)
{
Console.WriteLine("DDepartmentId: " + details.DDepartmentId);
Console.WriteLine("DDepartmentName: " + details.DDepartmentName);
Console.WriteLine("GEmployeeName: " + details.GEmployeeName);
Console.WriteLine("GEmployeeSalary: " + details.GEmployeeSalary);
Console.WriteLine(Environment.NewLine);
}
Console.WriteLine("=======================");
//First
Employee TempEmp = (from item in employeeList
where item.Id == 1
select item).First();
Console.WriteLine("Employee Id 1 : " + TempEmp.Name);
Console.WriteLine("=======================");
//FirstorDefault
TempEmp = (from item in employeeList
where item.Id == 10
select item).FirstOrDefault();
if(TempEmp!=null)
Console.WriteLine("Employee Id 10 : " + TempEmp.Name);
else
Console.WriteLine("Employee not found");
//Distinct, Except, Intersect, Union
Console.WriteLine("=======================");
int[] distEmpDeptIds = (from item in employeeList
select item.DeptId).Distinct().ToArray();
Console.WriteLine("Distinct Dept Id from Employee Collection");
foreach(int empDeptid in distEmpDeptIds)
{
Console.WriteLine(empDeptid);
}
Console.WriteLine("=======================");
int[] exceptEmpDeptIds = (from emp in employeeList
select emp.DeptId)
.Except( from dept in departmentList
select dept.DeptId).ToArray();
Console.WriteLine("Dept Id in Employee Collection but not in Department Collection");
foreach(int deptid in exceptEmpDeptIds)
{
Console.WriteLine(deptid);
}
Console.WriteLine("=======================");
int[] exceptDeptDeptIds = (from dept in departmentList
select dept.DeptId)
.Except( from emp in employeeList
select emp.DeptId).ToArray();
Console.WriteLine("Dept Id in Department Collection but not in Employee Collection");
foreach(int deptid in exceptDeptDeptIds)
{
Console.WriteLine(deptid);
}
List<int> exceptDeptDeptIdList = departmentList.Select(s => s.DeptId).Except(employeeList.Select(s => s.DeptId)).ToList();
Console.WriteLine("Dept Id in Department Collection but not in Employee Collection");
foreach(int deptid in exceptDeptDeptIdList)
{
Console.WriteLine(deptid);
}
Console.WriteLine("=======================");
int[] intersectDeptIds = departmentList.Select(s => s.DeptId).Intersect(employeeList.Select(s => s.DeptId)).ToArray();
Console.WriteLine("Dept Id in Department Collection and also in Employee Collection");
foreach(int deptid in intersectDeptIds)
{
Console.WriteLine(deptid);
}
Console.WriteLine("=======================");
int[] unionResultSet = departmentList.Select(s => s.DeptId).Union(employeeList.Select(s => s.DeptId)).ToArray();
Console.WriteLine("Union of Employee and Department DeptId");
foreach(int deptid in unionResultSet)
{
Console.WriteLine(deptid);
}
Console.WriteLine("=======================");
int[] unionAllResultSet = departmentList.Select(s => s.DeptId).Concat(employeeList.Select(s => s.DeptId)).ToArray();
Console.WriteLine("Union All of Employee and Department DeptId");
foreach(int deptid in unionAllResultSet)
{
Console.WriteLine(deptid);
}
//Take, TakeWhile, Skip, SkipWhile
Console.WriteLine("=======================");
List<Employee> takeEmployeeList = employeeList.OrderByDescending(o => o.Salary).Take(3).ToList();
Console.WriteLine("Top 3 Employee by Salary");
foreach(Employee emp in takeEmployeeList)
{
Console.WriteLine(emp.Name + ", " + emp.Salary);
}
Console.WriteLine("=======================");
List<Employee> takeWhileEmployeeList = employeeList.TakeWhile(i => i.Name.Contains("a")).OrderByDescending(o => o.Salary).ToList();
Console.WriteLine("Employees order by Salary with Name containing a");
foreach(Employee emp in takeWhileEmployeeList)
{
Console.WriteLine(emp.Name + ", " + emp.Salary);
}
Console.WriteLine("=======================");
List<Employee> skipEmployeeList = employeeList.OrderByDescending(o => o.Salary).Skip(3).ToList();
Console.WriteLine("Except Top 3 Employee by Salary");
foreach(Employee emp in skipEmployeeList)
{
Console.WriteLine(emp.Name + ", " + emp.Salary);
}
Console.WriteLine("=======================");
//Skip While
List<Employee> skipWhileEmployeeList = employeeList.OrderByDescending(o => o.Salary).SkipWhile(i => i.Name.Length > 6).ToList();
Console.WriteLine("Skip employees while name length > 6");
foreach(Employee emp in skipWhileEmployeeList)
{
Console.WriteLine(emp.Name + ", " + emp.Salary);
}
Console.WriteLine("=======================");
//using let
var letCollection = from emp in employeeList //outer sequence
join dept in departmentList //inner sequence
on emp.DeptId equals dept.DeptId
let bonus = dept.DeptName.Contains("Developer") ? emp.Salary * 0.1 : emp.Salary * 0.5
select new { DDepartmentId = dept.DeptId,
DDepartmentName = dept.DeptName,
EName = emp.Name,
ESalary = emp.Salary,
EBonus = bonus};
Console.WriteLine("DDepartmentId,DDepartmentName,EName,ESalary,EBonus");
foreach(var details in letCollection)
{
Console.WriteLine(details.DDepartmentId
+ "," + details.DDepartmentName
+ "," + details.EName
+ "," + details.ESalary
+ "," + details.EBonus);
}
}
}
LINQ TO XML
using System;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
public class Program
{
private static string bookXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><books><book id=\"1\"><ISBN>9780471779650</ISBN><title ln=\"en\">Beginning ASP.NET 2.0</title><category>Education</category><year>2005</year><price type=\"paperback\">555.00</price><publisher>WROX</publisher><authors><author type=\"editor\">Dr Chris Hart</author><author type=\"writer\">John Kauffman</author><author type=\"writer\">David Sussman</author><author type=\"writer\">Chris Ullman</author></authors></book><book id=\"2\"><ISBN>9781156287132</ISBN><title ln=\"en\">And Then There Were None</title><category>Fiction</category><year>2010</year><price type=\"hardcover\">331.00</price><price type=\"paperback\">179.00</price><price type=\"audio_cd\">1710.00</price><publisher>HarperCollins</publisher><authors><author type=\"writer\">Agatha Christie</author></authors></book><book id=\"3\"><ISBN>9780091428709</ISBN><title ln=\"en\">Thank You, Jeeves</title><category>Fiction</category><year>2008</year><price type=\"hardcover\">727.00</price><price type=\"paperback\">207.80</price><publisher>RHUK</publisher><authors><author type=\"writer\">P. G. Wodehouse</author></authors></book><book id=\"4\"><ISBN>9788170664802</ISBN><title ln=\"bn\">Kalbela</title><category>Fiction</category><year>2005</year><price type=\"hardcover\">338.00</price><price type=\"paperback\">329.00</price><publisher>Ananda Publishers Pvt Ltd.</publisher><authors><author type=\"editor\">Shubhra Roy</author><author type=\"writer\">Samaresh Majumder</author></authors></book><book id=\"5\"><ISBN>9789382300250</ISBN><title ln=\"bn\">Sukanto Samagra</title><category>Poetry</category><year>2012</year><price type=\"hardcover\">150.00</price><publisher>Parul Prakashani</publisher><authors><author type=\"writer\">Sukanto Bhattacharya</author></authors></book></books>";
public static void Main()
{
Console.WriteLine("========================");
IEnumerable<XElement> books;
//1. How Do I Read XML using LINQ to XML
//using XElement
XElement rootXelement = XElement.Parse(bookXml);
books = rootXelement.Elements();
// Read the entire XML
foreach (var book in books)
{
//Console.WriteLine(book);
}
Console.WriteLine("========================");
//using XDocument
XDocument rootXdocument = XDocument.Parse(bookXml);
books = rootXdocument.Elements();
foreach (var book in books)
{
//Console.WriteLine(book);
}
Console.WriteLine("========================");
//2. How Do I Access a Single Element using LINQ to XML
XElement rootXE = XElement.Parse(bookXml);
books = rootXE.Elements();
Console.WriteLine("List of all Book Titles :");
foreach (XElement book in books)
{
//Console.WriteLine(book.Element("title").Value);
}
Console.WriteLine("========================");
//3. How Do I Access Multiple Elements using LINQ to XML
Console.WriteLine("List of all Book Titles along with their ISBN:");
foreach (XElement book in books)
{
/*Console.WriteLine("{0} has ISBN {1}",
book.Element("title").Value,
book.Element("ISBN").Value);*/
}
Console.WriteLine("========================");
//4. How Do I Access all Elements having a Specific Value using LINQ to XML
var eduBooks = from item in rootXE.Elements("book")
where item.Element("category").Value == "Education"
select item;
Console.WriteLine("Details of Education Books:");
foreach (XElement eduBook in eduBooks)
//Console.WriteLine(eduBook);
Console.WriteLine("========================");
//5. How Do I access Specific Element having a Specific Attribute using LINQ to XML
/*var acdBooks = from item in rootXE.Elements("book")
where (string)item.Element("price") == "audio_cd"
select item;*/
var acdBooks = from item in rootXE.Elements("book").Elements("price")
where (string)item.Attribute("type") == "audio_cd"
select item.Parent;
Console.WriteLine("Details of Audio_CD Books:");
foreach (XElement book in acdBooks)
{
//Console.WriteLine(book);
}
Console.WriteLine("========================");
//6. How Do I Find an Element within another Element using LINQ to XML
var acBooks = from item in rootXE.Elements("book").Elements("authors").Elements("author")
where (string)item == "David Sussman"
select item.Parent.Parent;
Console.WriteLine("Details of David Sussman Books");
foreach (XElement book in acBooks)
{
//Console.WriteLine(book);
}
Console.WriteLine("========================");
//7. How Do I Find Nested Elements (using Descendants Axis) using LINQ to XML
Console.WriteLine("List of all authors");
foreach (XElement author in rootXE.Descendants("author"))
{
//Console.WriteLine(author.Value);
}
Console.WriteLine("========================");
//8. How do I apply Sorting on Elements using LINQ to XML
IEnumerable<XElement> booksByPrice = from item in rootXE.Elements("book")
let pub = item.Element("publisher").Value
orderby pub
select item;
Console.WriteLine("List and Sort all Books by publisher");
foreach (XElement book in booksByPrice)
{
/*Console.WriteLine("\"{0}\" is published by {1}",
book.Element("title").Value,
book.Element("publisher").Value);*/
}
Console.WriteLine("========================");
//9. Find Element at a Specific Position using LINQ to XML
XElement firstTitle = rootXE.Descendants("title").ElementAt(1);
Console.WriteLine("Second Book title: " + firstTitle.Value);
Console.WriteLine("========================");
//10. List the 2nd and 3rd Element using LINQ to XML
List<XElement> bookList = rootXE.Descendants("book").Skip(1).Take(2).ToList();
foreach (XElement book in bookList)
{
//Console.WriteLine(book);
}
Console.WriteLine("========================");
//11. List the Last 2 Elements using LINQ To XML
bookList = rootXE.Descendants("book").Reverse().Take(2).ToList();
bookList = rootXE.Descendants("book").Reverse().Take(2).Reverse().ToList();
foreach (XElement book in bookList)
{
//Console.WriteLine(book.Attribute("id") + ", " + book.Element("ISBN") + ", " + book.Element("title"));
}
//12. Add a new Element at runtime using LINQ to XML
rootXE.Add(new XElement("book",
new XAttribute("id", 6),
new XElement("ISBN", 9781405206143),
new XElement("title",
new XAttribute("ln","bl"),
"Tintin in America"
),
new XElement("category","Comics"),
new XElement("year","2019"),
new XElement("price",
new XAttribute("type","hardcover"),338),
new XElement("price",
new XAttribute("type","paperback"),329),
new XElement("publisher","HC"),
new XElement("authors",
new XElement ("author",
new XAttribute("type", "editor"), "Prakriti"),
new XElement ("author",
new XAttribute("type", "writer"), "Biswajit")
)));
//Console.WriteLine(rootXE);
rootXE.Add(XElement.Parse("<book id=\"6\"><ISBN>9781405206143</ISBN><title ln=\"bl\">Tintin in America</title><category>Comics</category><year>2019</year><price type=\"hardcover\">338</price><price type=\"paperback\">329</price><publisher>HC</publisher><authors><author type=\"editor\">Prakriti</author><author type=\"writer\">Biswajit</author></authors></book>"));
Console.WriteLine(rootXE);
}
}
No comments:
Post a Comment