Although strictly speaking this is not a bug, IMHO the way the ProjectTrackers example fills the lists using LINQ is not optimal.
For example, in RoleList.DataPortal_Fetch() adding
ctx.DataContext.Log = Console.Out;
at the beginning of the method shows (in the output window of the debugger) that the generated query is:
SELECT [t0].[Id], [t0].[Name], [t0].[LastChanged]
FROM [dbo].[Roles] AS [t0]
This gets all columns from the database, including the unused LastChanged. Not a big deal in this particular situation, but could be worse for a table with many columns.
Moving the new NameValuePair(role.Id, role.Name) into the query expression instead of the foreach loop:
var data = from r in ctx.DataContext.Roles
select new NameValuePair(r.Id, r.Name);
IsReadOnly = false;
foreach (var role in data)
this.Add(role);
IsReadOnly = true;
allows LINQ to only query the needed columns:
SELECT [t0].[Id] AS [key], [t0].[Name] AS [value]
FROM [dbo].[Roles] AS [t0]
Adding an AddRange(IEnumerable<T>) to ExtendedBindingList<T> would then allow to write
this.AddRange(data);
instead of the loop, or even
this.AddRange(from r in ctx.DataContext.Roles
select new NameValuePair(r.Id, r.Name));
In more complex situations, where the query is created in several steps (such as in ProjectList), the select new ... has to be done at the very end, by adding a last step to the query construction. You can for example substitute this for the foreach loop:
this.AddRange(from p in data
select new ProjectInfo(p.Id, p.Name));
The original query (with optional filter)
SELECT [t0].[Id], [t0].[Name], [t0].[Started], [t0].[Ended], [t0].[Description], [t0].[LastChanged]
FROM [dbo].[Projects] AS [t0]
WHERE [t0].[Name] LIKE @p0
-- @p0: Input VarChar (Size = 10; Prec = 0; Scale = 0) [%Business%]
then becomes
SELECT [t0].[Id] AS [id], [t0].[Name] AS [name]
FROM [dbo].[Projects] AS [t0]
WHERE [t0].[Name] LIKE @p0
-- @p0: Input VarChar (Size = 10; Prec = 0; Scale = 0) [%Business%]
Copyright (c) Marimer LLC