Reputation: 363
I have a entity database, created from sql database. I need to show record on datagridview, i am using this code.
DBEntities db = new DBEntities();
dataGridView1.DataSource = db.Agent.Select(x => new { Name = x.Name, Second_Name = x.Second_Name}).ToList();
It's example, real agent table contain around 10 columns, and i need to show all, exept 'id'. If i do same for every 8 columns, become a long and senseless row. How to do it more obliviuous and good.
Upvotes: 1
Views: 4009
Reputation: 180777
If you don't want to use an anonymous type to specify the fields you want, you can:
Select
except for the ID, orThere's no Select Except
statement in Linq. However, you can use this extension method to accomplish the same thing:
/// <summary>
/// Returns all fields/properties from <paramref name="source"/> except for the field(s)/property(ies) listed in the selector expression.
/// </summary>
public static IQueryable SelectExcept<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector )
{
var newExpression = selector.Body as NewExpression;
var excludeProperties = newExpression != null
? newExpression.Members.Select( m => m.Name )
: new[] { ( (MemberExpression)selector.Body ).Member.Name };
var sourceType = typeof( TSource );
var allowedSelectTypes = new Type[] { typeof( string ), typeof( ValueType ) };
var sourceProperties = sourceType.GetProperties( BindingFlags.Public | BindingFlags.Instance ).Where( p => allowedSelectTypes.Any( t => t.IsAssignableFrom( ( (PropertyInfo)p ).PropertyType ) ) ).Select( p => ( (MemberInfo)p ).Name );
var sourceFields = sourceType.GetFields( BindingFlags.Public | BindingFlags.Instance ).Where( f => allowedSelectTypes.Any( t => t.IsAssignableFrom( ( (FieldInfo)f ).FieldType ) ) ).Select( f => ( (MemberInfo)f ).Name );
var selectFields = sourceProperties.Concat( sourceFields ).Where( p => !excludeProperties.Contains( p ) ).ToArray();
var dynamicSelect =
string.Format( "new( {0} )",
string.Join( ", ", selectFields ) );
return selectFields.Count() > 0
? source.Select( dynamicSelect )
: Enumerable.Empty<TSource>().AsQueryable<TSource>();
}
Further Reading
Use SelectExcept When You Are Too Lazy to Type
Upvotes: 4
Reputation: 6251
This question is answered here and it is definitely possible. You can cast the selected columns again into enumerable of the original object if the undesired properties are nullable or you can use anonymous.
For example :
Full query tested in LINQ Pad agains real table
from l in Lessons
select new
{
l.Id,
l.Description,
l.LanguageId,
l.CreatedOn
}
has resulting SQL :
SELECT [t0].[Id], [t0].[Description], [t0].[LanguageId], [t0].[CreatedOn]
FROM [Lessons] AS [t0]
The cut version tested in LINQ Pad with less columns
from l in Lessons select new { l.CreatedOn }
has resulting SQL :
SELECT [t0].[CreatedOn]
FROM [Lessons] AS [t0]
After all that you can hide a column in the dataGridView.
If you do not want to write the anonymous object you can use AutoMapper as @ maruthu chandrasekaran suggested.
This way you will be able to server your linq query reduced and map it to your object in one row without the jitter of anonymous object. You can create a DTO object too. Using Entity-EntityDto mappings with AutoMapper is an easy job.
Upvotes: 0
Reputation: 168
Why don't you use automapper to convert the entity object to a domain object?
Mapper.CreateMap<Agent, AgentDto>();
dataGridView1.DataSource = db.Agent.Select(x => Mapper.Map<AgentDto>(x)).ToList();
The AgentDto will contain all the fields except 'Id'
Upvotes: 1