I have a class that has 3 properties:
class Three
{
int ID { get; set ;}
string Name { get; set; }
double Value { get; set; }
}
I then have a linq query that returns a Queryable<Three> but only ID and Name are defined within the table.
var three = from t in db.Threes
select t;
three = { {ID=1, Name="A", Value=0},{ID=2, Name="B", Value=0},...}
So Value is not defined within the db.Threes table so it defaults to 0 as doubles do. I then iterate over each item in var three to set Value based upon another table:
for (int i = 0; i < three.Count(); i++)
{
three[i].Value = (from v in db.Values
where v.ThreeID = i.ID
select v.Value).First();
}
return three;
The Queryable<Three> three now contains definitions for .Value:
three = { {ID=1, Name="A", Value=99},{ID=2, Name="B", Value=100},...}
The key thing that I'm trying to do is to still return a Queryable<Three>, but to also set the Value property.
Is there a better way to do this instead of using a for loop?
I'd like to be able to extend this to any class with a Value property that is assigned from another table; suppose I have a class Four:
class Four
{
int ID {get; set;}
string Name {get; set;}
DateTime Date {get; set;}
double Value {get; set;}
}
The first query would populate with ID, Name and Date and I still want to be able to assign Value. I feel like there is a better way to do this with linq that I just can't come up with.
Edit: suppose I'm calling db.GetTable<T> and Three and Four are really generic arguments that implement a .Value interface. I can't explicitly instantiate a generic type because I would have to hard code the properties.
I think you are looking for join. You are assigning values from another table whose id is the same as the Three table.
You can build back a Three object like this:
var three = from t in db.Threes
join v in db.Values on t.ID equals v.ThreeID
select new Three{
ID = t.ID,
Name = t.Name,
Value = v.Value
};
What you were doing before by looping, that is a performance hit. What happens is that you called to the database to loop it, then for each loop, you make another call back to the database. If your tables are linked by those Ids, then using this code makes 1 single database call and no in memory looping.
What about a simple join, assuming you have some common key?
var things = from t in db.Threes
join v in db.Values on t.SomeId equals v.SomeId
select new Three { ID = t.ID,
Name = t.Name,
Value = v.Value
};
Related
This is my SQL query:
SELECT TOP 1000
s.id, s.[index], s.staffini,
MIN(accessdate) AS [In],
MAX(accessdate) AS [Out],
sa.mode, sa.daytype
FROM
staffattendances AS sa
INNER JOIN
staffs AS s ON sa.staffid = s.id
GROUP BY
staffid, CAST(accessdate AS DATE), s.staffname,
sa.mode, sa.daytype, s.[index], s.staffini, s.id
How to convert this to a Linq lambda query?
var tmp = Context.staffAttendances
.Include(t => t.staff)
.GroupBy(s => new
{
s.StaffId, s.,
s.AccessDate,
s.staff.StaffName,
s.Mode, s.Daytype,
s.staff.index, s.staff.Id
})
.Select(x => new staffattdto
{
index = x.Key.index,
StaffIni = x.Key.StaffName,
In = x.Max(t => t.AccessDate),
Out = x.Max(t => t.AccessDate),
mode = x.Key.Mode,
daytype = x.Key.Daytype,
})
.OrderByDescending(t => t.In);
I personally prefer using linq query syntax for these kind of queries.
Sample below:
var results = (from o in Organizations
join m in Members on o.OrganizationId equals m.OrganizationId
group o by new { o.OrganizationId, m.MemberId } into g
select new
{
g.Key.OrganizationId,
g.Key.MemberId
})
.Take(1000);
Alas you forgot to mention your classes and the relations between the tables, so I have to make a guess.
So you have Staffs and StaffAttendances. It seems to me that there is a one-to-many relation between Staffs and StaffAttendances: every Staff has zero or more StaffAttendances; every StaffAttendance belongs to exactly one Staff, namely the Staff that foreign key StaffAttendance.StaffId refers to.
You will have classes similar to the following:
class Staff
{
public int Id {get; set;}
public string Name {get; set;}
public string Ini {get; set;}
...
// Every Staff has zero or more StaffAttendances (one-to-many)
public virtual ICollection<StaffAttendance> StaffAttendances {get; set;}
}
class StaffAttendance
{
public int Id {get; set;}
public string Mode {get; set;}
public int DayType {get; set;}
...
// every StaffAttendance belongs to exactly one Staff, using foreign key
public int StaffId {get; set;}
public virtual Staff Staff {get; set;}
}
I'm trying to figure out what your query does. It seems something like: "From every Staf, with its zero or more StaffAttendances give me the Id, the StaffName, (maybe some more Staff properties), and from all its StaffAttendances with the same Mode and DayType give me the minimum and maximum StafAttendance AccessDate"
In entity framework always use Select to query data and select only the properties that you actually plan to use. Only use Include if you plan to change the included data.
The reason for this is that Include will fetch the complete object, inclusive the properties that you won't use. If you have a database with Schools and Students, then every Student will have a foreign key to the School that he attends. Every Student on School [10] will have a foreign key SchoolId with a value [10].
If you use Include to query "School [10] with all its 2000 students" you will be transferring the value 10 more than 2000 times, while you already know this value.
Use the virtual ICollection
I think your query will be something like:
var result = dbContext.Staffs
// only if you don't want all Staffs:
.Where(staff => ...)
.Select(staff => new
{
Id = staff.Id,
Ini = staff.StaffIni,
Attendance = staff.StaffAttendances.GroupBy(attendance => new
{
Mode = attendance.Mode,
DayType = attendance.DayType,
},
// parameter resultSelector, for every [Mode, DayType] combination,
// and all StaffAttendances that have this [Mode, DayType] combination
// make one new:
(modeDayType, staffAttendancesWithThisModeDayType) => new
{
Mode = modeDayType.Mode,
DayType = modeDayType.DayType,
In = staffAttendancesWithThisModeDayType
.Select(staffAttendance => staffAttendance.AccessDate)
.Min(),
Out = staffAttendancesWithThisModeDayType
.Select(staffAttendance => staffAttendance.AccessDate)
.Max(),
},
});
Entity framework knows the relations between your tables, and translates the usage of your virtual ICollection into the proper GroupJoin.
It seems to me that you want some more properties. Since I use entity framework my SQL is a bit rusty, but I guess you'll get the gist.
I think that you don't have a Min / Max for DateTime. If you don't, you'll have to convert them to Ticks and back:
In = new DateTime(staffAttendancesWithThisModeDayType
.Select(staffAttendance => staffAttendance.AccessDate.Ticks)
.Min()),
If you are using this more often, consider to create an Extension method for this, they are one-liners, and because you reuse them it might save you a lot of time unit testing them:
public static DateTime MinAccessDate(this IQueryable<StaffAttendance> attendances)
{
return attendances.Select(attendance => attendance.AccessDate).Min();
}
public static DateTime Min(this IQueryable<DateTime> dates)
{
return new DateTime(dates.Select(date => date.Ticks).Min());
}
Usage:
In = staffAttendancesWithThisModeDayType.MinAccessDate(),
Out = staffAttendancesWithThisModeDayType.MaxAccessDate(),
In my opinion, using the virtual ICollection in a one-to-many relationship is the method that is by far the easiest to understand. Unit tests will also be easier, because your input data can come from Dictionaries or Lists instead of from real databases.
Do the GroupJoin yourself
Some people use a version of entity framework that doesn't understand the virtual ICollection, or they prefer to do the GroupJoin to fetch the Staff with their Attendances themselves. The second halve of the query will be similar:
var result = dbContext.Staffs.GroupJoin(dbContext.StaffAttendances,
staff => staff.Id, // from every Staff take the primary key
attendance => attendance.StafId, // from every StaffAttendance take the foreign key
// parameter resultSelector: for every Staff, and its zero or more StaffAttendances
// make one new
(staff, attendancesOfThisStaff) => new
{
Id = staff.Id,
Ini = staff.StaffIni,
Attendance = staff.attendancesOfThisStaff.GroupBy(attendance => new
{
Mode = attendance.Mode,
DayType = attendance.DayType,
},
// etc. see above
});
I'm trying to perform a simple query and the result data is almost all null.
I have this table structure
Table Registros
ID | Autonumeric
TareaM_Id | Numeric
Fecha | Date/Time
and Macro_tareas table
ID | Autonumeric
Nombre | Short Text
I have mapped the classes in C# like this:
[Table("Registros")]
public class Registro
{
[Column("ID")]
public virtual int ID { get; set; }
[Column("Fecha")]
public virtual DateTime Fecha { get; set; }
[Column("TareaM_Id")]
public virtual int TareaM_Id { get; set; }
public virtual MacroTarea MacroT { get; set; }
}
[Table("Macro_tarea")]
public class MacroTarea
{
[Column("ID")]
public virtual int ID { get; set; }
[Column("Nombre")]
public virtual string Nombre{ get; set; }
public virtual ICollection<Registro> Registros { get; set; }
}
This is the query i'm trying to use
string sql = #"SELECT reg.ID, mac.ID
FROM Registros as reg INNER JOIN Macro_tarea as mac on reg.TareaM_Id = mac.ID
WHERE Fecha = #Fecha";
using (IDbConnection db = new OleDbConnection(ConnectionString))
{
var result = db.Query<Registro,MacroTarea, Registro>(sql,
(reg,mac) =>
{
reg.MacroTarea = mac;
return reg;
}
,new { #Fecha = new DateTime(2019, 1, 4).Date }
, splitOn: "mac.ID")
.AsList();
}
I'm trying to only retrieve ids, but both id become null why is this happening?
The thing is, if I add Registros.Fecha and Macro_tarea.Nombre to the query, it got the value correctly. But id keep coming null.
Apparently the issue is happening only with ids. I suspect this issue is due to duplicate column names.
I'm working with Microsoft Access just in cast that matters.
My question is not similar to the possible duplicate because I have the classes defined as they should be mapped.
Renaming your database columns because your code cannot cope with the data is not a good idea. In the world of separation of concerns, why should your database care? There are good database reasons to name ID columns "Id", and you may not even have the option to change them.
There's another issue with Dapper mapping that renaming columns does not get around; repeated types. If you are trying to map to more than one instance of a class Dapper gets confused, and renaming columns won't work because you will rename both instances.
Here is the solution I have come up with. It's similar to a lot of examples that use a dictionary, except:
it can nest to as many levels as you like
can cope with Dappers 7 item limit
can cope with duplicates of the same class
can be reused e.g., for Get, GetCurrent and GetAll
In this example there is an Auction that has many Lots. Each Lot may have 1 or many Items. Items might be packs of Items. The Items are from a limited catalogue and we like relational data, so a Things table contains the details on each Item, like colour, size, etc. Here we are only getting a single Lot, but getting an Auction is the same with another level on top for Auction.
Parameter 1 - The SQL to get everything in one go
Parameter 2 - A Type array of each object we'll get back. For this reason it's best to order your SELECT to group the fields into the classes
Parameter 3 - Call the method we're about to write with the SQL result
Parameter 4 - Standard parameter array for the SQL. SQL Injection is bad, m'kay?
public async Task<List<Lot>> GetAll(int auctionId)
{
using (var connection = new SqlConnection(_appSettings.ConnectionString))
{
await connection.OpenAsync();
var result = new List<Lot>();
await connection.QueryAsync($#"
SELECT [Lot].*,
[Item].[Id],
[Item].[LotId],
[Item].[Notes],
itemDetails.[Id],
itemDetails.[ThingId],
itemDetails.[Colour],
itemDetails.[Size],
[SubItem].[Id],
[SubItem].[ItemId],
[SubItem].[Notes],
subItemDetails.[Id],
subItemDetails.[ThinId],
subItemDetails.[Colour],
subItemDetails.[Size]
FROM [Lot]
INNER JOIN [Item] ON [Item].[LotId] = [Lot].[Id]
LEFT JOIN [Thing] AS itemDetails ON itemDetails.[Id] = [Item].[ThingId]
LEFT JOIN [SubItem] ON [SubItem].[ItemId] = [Item].[Id]
LEFT JOIN [Thing] AS subItemDetails ON subItemDetails.[Id] = [SubItem].[ThingId]
WHERE [AuctionId] = #{nameof(auctionId)}
ORDER BY [Lot].[Id], [Item].[Id], [Expansion].[Id];",
new Type[] {
typeof(Lot),
typeof(Item),
typeof(Thing),
typeof(Expansion),
typeof(Thing)
},
MapResult(result),
new
{
AuctionId = auctionId
}
);
return result.ToList();
}
}
private Func<object[], Lot> MapResult(List<Lot> result)
{
return (obj) =>
{
Lot lot = (Lot)obj[0];
Item item = (Item)obj[1];
Thing itemDetails = (Thing)obj[2];
SubItem subItem = (SubItem)obj[3];
Thing subItemDetails = (Thing)obj[4];
if (lot != null)
{
if (result.Any(a => a.Id == lot.Id))
{
lot = result.First(a => a.Id == lot.Id);
}
else
{
result.Add(lot);
}
}
if (item != null)
{
if (lot.Items.Any(i => i.Id == item.Id))
{
item = lot.Items.First(i => i.Id == item.Id);
}
else
{
lot.Items.Add(item.FromThing(itemDetails));
}
}
if (expansion != null)
{
if (item.SubItems.Any(e => e.Id == subItem.Id) == false)
{
item.SubItems.Add(subItem.FromThing(subItemDetails));
}
}
return null;
};
}
MapResult is the meat of the code. It returns a Func with two types, the Type array we defined above and the return Type, and takes a List of the top level object.
I then map each item from the object array to another of it's actual type. This keeps the code easier to read, and enables properties and methods of the object to be accessed without issue.
Then it's a case of stepping down the hierarchy, checking at each step if one already exists with a matching id, and swapping the iterator to a reference to it if it does. This means that following code will add to the existing item.
In the particular case I've also added a FromThing function to allow easier combining of object properties.
As we discussed in comments, this is an issue due to duplicate column names in two tables. This is where the similar issue and solution could be found. But, it does not include "mapping by code" as you said. So it is not exact duplicate.
I suggest you change the names of ID fields in your tables to avoid colliding them. Of-course, you should also change the name of your POCO properties and mappings accordingly.
If you cannot change the column names in table, change the POCO property name, and use the column alias in SQL query to match those new property names.
I hope this helps you.
The problem was effectively the name of the properties.
I solved it using Custom Column Mapping to do it i got two possible solutions:
Without extensions
First, we define a Dictionary with the name of the column as key, and the name of the property as value
IDictionary<string, string> columnMaps = new Dictionary<string, string>()
{
{ "Macro_tarea.ID", "ID" },
{ "Registros.ID", "ID" }
};
Then, we define a delegate to obtain the PropertyInfo object of the property to which we intend to assign the alias of the previous dictionary
var mapper = new Func<Type, string, PropertyInfo>((type, columnName) =>
{
if (columnMaps.ContainsKey(columnName))
return type.GetProperty(columnMaps[columnName]);
else
return type.GetProperty(columnName);
});
Now, we define an object that implements the ITypeMap interface using CustomPropertyTypeMap implementation
ITypeMap MacroTareaMapper = new CustomPropertyTypeMap(typeof(Macro_tarea),
(type, columnName) => mapper(type, columnName));
ITypeMap RegistrosMapper = new CustomPropertyTypeMap(typeof(Registros),
(type, columnName) => mapper(type, columnName));
Then we register them
SqlMapper.SetTypeMap(typeof(Macro_tarea), MacroTareaMapper);
SqlMapper.SetTypeMap(typeof(Registros), RegistrosMapper);
Simpler solution with Dapper.FluentMap
It is implemented as follows:
We create a class that inherits from EntityMap<T> and using the Map method we define which column corresponds to each property. For example,
internal class Macro_tareaMap : EntityMap<Macro_tarea>
{
internal Macro_tareaMap()
{
//Mi propiedad ID esta asociada a la columna Macro_tarea.ID
Map(x => x.ID).ToColumn("Macro_tarea.ID");
}
}
Then just register it
FluentMapper.Initialize((config) =>
{
config.AddMap(new Macro_tareaMap());
});
Hope it helps another people!
Source: https://medium.com/dapper-net/custom-columns-mapping-1cd45dfd51d6
Hi Have a two tables that have a relationship like below ..
class Boothtable
{
public int BoothId {get;set;}
public string BoothName {get;set;}
public double Price {get;set;}
public int RoomId{get;set;}
}
class RoomTable
{
public int RoomId {get;set;}
public string RoomName{get;set;}
public sting Location {get;set;}
}
I am trying to write a join query using LINQ to join the the boothtable to the roomstable on RoomId and return all properties from the boothtable and only return the RoomName property from the Rooms table. is there anyone that can direct me how to achieve this?
So far i have a linq exp like this but it only returns all properties from the booths table.
var getData = from boothtable in context.Boothtable
join roomtable in context.RoomTable
on boothtable.RoomId equals roomtable.RoomId
where boothtable.BoothId == someId
select boothtable;
If you want to retrieve properties from both you must project an object containing data from both. This uses an anonymous object to do so:
select new { boothtable, roomtable }
If you want to return this collection of anonymous objects from a method then define a custom object with the two properties and instantiate it
select new YourCustomObjet { Booth = boothtable, Room = roomtable }
If you only want some of the properties (missed it at first) then as you project the objects in the examples above just project the specific fields:
select new
{
boothtable.BoothId,
boothtable.BoothName,
boothtable.Price,
roomtable.RoomName
}
Notice that if it is an anonymous object and the desired property names are the same, no need to explicitly define a name
Try this -
var getData = (from boothtable in context.Boothtable
join roomtable in context.RoomTable
on boothtable.RoomId equals roomtable.RoomId
where boothtable.BoothId == someId
select new
{
BoothId = boothtable.BoothId,
BoothName = boothtable.BoothName,
Price = boothtable.Price,
RoomName = roomtable.RoomName
});
I want to process the data from my database-query using raw SQL in Entity Framework 6 as follows and need a best practice by the use of native functions of C# and LINQ:
PICTURE 1: Resultset taken from database
I have created a class for the resultset above, it looks like that:
public class ProjectQueryModel {
public int Project { get; set; }
public string Projectname { get; set; }
public int RoomId { get; set; }
public string RoomName { get; set; }
public int? EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int? QualificationId { get; set; }
public string QualificationName { get; set; }
public int? QualificationLevel { get; set; }
}
To this point the query works and I got all my data from it stored in a List of type ProjectQueryModel. Now I want to add this data to my ViewModel and don't know how to use the functions C# offers me to process the data of resultsets. How can I achieve the following by saving every entity of type ProjectViewModel in a List, whose objects have the following structure:
PICTURE 2: data organisation in ViewModel
An example dataset for project 1 in the target list should look like this:
ProjectId = 1
Projectname = T1
RoomId = 1
RoomName = Delta Room
======================
Employees *(Attribute of type List <ProjectEmployeesVM> )*
[0].EmployeeId = 2
[0].EmployeeName = Mee
[0].EmployeeQualifications *(Attribute of type List<EmployeeQualificationsVM)*
[0].EmployeeQualifications[0].QualificationId = 1
[0].EmployeeQualifications[0].QualificationName = Programmer
[0].EmployeeQualifications[0].QualificationLevel = 3
...any other qualification of the employee
[1].EmployeeId = 2
[1].EmployeeName = Mee
[1].EmployeeQualifications
[1].EmployeeQualifications[0]
...Any other employee in this project and all of his qualifications
What I also want to achieve is to save a empty list in case the project has no employees, because the resultset is achieved by the use of LEFT OUTER JOINS. For the qualifications it is not necessary, because every employee has at least one qualification.
VERY BIG THANKS in advance
I'm supposing you have a constructor in every class involved that takes all the properties as arguments.
Here's how i would do it:
List<ProjectQueryModel> queryResult = ...;
List<ProyectViewModel> views = queryResult
// Take all the rows that belong to one proyect
.GroupBy(m => m.Proyect)
// Convert every group into a ProyectViewModel
// First use Select to Map every Group into a new Proyect using a function that takes a group of rows and return a Proyect
// Then we use Aggregate inside that mapping function to collapse the entire group of rows into a single ProyectViewModel
// We'll need a contructor in ProyectViewModel that gives us a completly empty instance
// Aggregate takes a starting point, and a function that takes that starting point, and passes it every element of the IEnumerable we're using. The return value of that function is the "new starting point".
// Using this we'll build the Proyect from every row.
.Select(g => g.Aggregate(new ProyectViewModel(), (pvm, nxtRow) => {
// Check if we haven't initialized the instance, and do so.
if (pvm.ProyectId == null) pvm.ProyectId = nxtRow.Proyect;
if (pvm.ProyectName == null) pvm.ProyectName = nxtRow.ProyectName;
if (pvm.RoomId == null) pvm.RoomId = nxtRow.RoomId;
if (pvm.RoomName == null) pvm.RoomName = nxtRow.RoomName;
if (pvm.Employees == null) pvm.Employees = new List<ProyectEmployeeViewModel>();
// If the row has an employee
if (nxtRow.EmployeeId.HasValue) {
// If the Employee is not yet on the Proyect add it
if (!pvm.Employees.Any(e => e.EmployeeId == nxtRow.EmployeeId))
{
// This constructor should create the empty List of Qualifications
pvm.Employees.Add(new ProyectEmployeeViewModel(nxtRow.EmployeeId.Value, nxtRow.EmployeeName);
}
// If the row has a qualification
if (nxtRow.QualificationId.HasValue)
{
// Find it's employee
pvm.Employees.First(e => e.EmployeeId == nxtRow.EmployeeId)
// Add the current row's qualification to the employee
.Qualifications.Add(new EmployeeQualificationsViewModel(nxtRow.QualificationId.Value, nxtRow.QualificationName, nxtRow.QualificationLevel.Value));
}
}
// Return the Proyect with the changes we've made so we keep building it
return pvm;
})).ToList();
LINQ is quite a beauty isn't it?
There might be errors, but use this as a starting point.
Start by making sure that your database has the right foreign key constraints between your tables, then update your model. This will automatically create the correct navigation properties. I've assumed they will be called Employees and Qualifications, but change as appropriate.
Then your query just becomes:
var result=db.Projects
.Include(p=>p.Employees)
.Include(p=>p.Employees.Select(e=>e.Qualifications))
.Where(p=>p.id==1)
.AsEnumerable(); // or .ToList() if you prefer
Then just pass IEnumerable<Project> to your view (or just Project if your view will always only get 1 Project -- in that case, just end the query with .First() instead of .AsEnumerable()) . Unless of course you like creating ViewModels, but I'm guessing you don't and this isn't a project that needs the added complexity or abstractions.
The above code assumes you have the following tables:
Project (int Id, varchar(50) Name, int RoomId)
Room (int Id, int Name)
Employee (int Id, varchar(50) Name)
Qualification (int Id,varchar(50) Name, int Level)
Cross Reference tables:
ProjectEmployees (int ProjectId, int EmployeeId)
EmployeeQualifications (int EmployeeId, int QualificationId)
Foreign Keys:
Project.RoomId -> Room.Id
ProjectEmployees.ProjectId -> Project.Id
ProjectEmployees.EmployeeId -> Employee.Id
EmployeeQualifications.EmployeeId -> Employee.Id
EmployeeQualifications.QualificationId -> Qualification.Id
I have a one class to one table mapping; unfortunately this table has 110+ columns, and queries take a long time process, especially when most of the time I only want to view <10 columns.
My problem is that the queries are dynamically generated based on what the user wants to look at. I can't really create different mappings with different columns because there would be a very large number of combinations. I'm using the criteria API to generate the queries. Can I also use this to only select the columns the user wants? Or some other method?
Thanks
Easy to do with LINQ (assuming you're using NHibernate 3.0 or later):
var products = from p in Session.Query<Product>()
where // ...some query (snip)
select new
{
Name = p.ProductName,
Description = p.ShortDesc,
Price = p.Price,
Units = p.Quantity
};
Also, if you're using HQL, you can just select the columns you need similar to using T-SQL, but use a Transformer to get a strongly typed object back:
First create a class with your narrowed down columns:
public class ProductReport
{
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int Units { get; set; }
}
Then your query:
string hql = "select p.ProductName as Name, p.ShortDesc as Description ...(snip) " +
"from Product p " +
"where ...some query (snip)";
IQuery query = Session.CreateQuery(hql)
.SetResultTransformer(Transformers.AliasToBean<ProductReport>());
IList<ProductReport> products = query.List<ProductReport>();
Just sure make the aliases in your query (as Name, as Description etc.) match the property names in your class.
In addition to the example Tim gave you can do something like this:
IList selection =
session.QueryOver<Cat>()
.Select(
c => c.Name,
c => c.Age)
.List<object[]>();
Above example was taken from: http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx
Use a ProjectionList to select the columns you want. See here for the examples.