I have 2 SQL-Tables, which I created via SQL Server Managment Studio (including PK & FK):
In my WinForm Project in Visual Studio, I added the data-model via Code First to an Existing Database and read the data via the following linq-query:
dataGridView1.DataSource = dbContext.deliveries.OrderBy(d => d.id).ToList();
Now the datagridView1 consists of the columns from the table "deliveries", but instead of showing a column customer_id I would like show the corresponding name and adress of the customer.
Some other answers on stackoverflow suggest to edit the query and use the "include" property. So I tried to use
deliveries.Include(d=>d.customer.name).OrderBy(d => d.id).ToList();
but this throws an Exception while running with the folowing Error:
The EntityType '*.customer' does not declare a navigation property with the name 'name'
which I dont understand, since my Classes follow the form of https://docs.microsoft.com/en-us/ef/ef6/fundamentals/relationships AND are created via Code First from existing database.
public partial class deliveries
{
public int id { get; set; }
public int? amount { get; set; }
public int? customer_id { get; set; }
[ForeignKey("customer_id")]
public virtual customer customer { get; set; }
}
public partial class customer
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public customer()
{
deliveries = new HashSet<deliveries>();
}
[Key]
public int customerID { get; set; }
[StringLength(50)]
public string name { get; set; }
[StringLength(10)]
public string address { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<deliveries> deliveries { get; set; }
}
CodePudding user response:
If you want to show only specific values, you have to do custom projection and specify shape of your result via Select
. It can be DTO or anonymous class, and no Includes are needed.
var result = deliveries
.OrderBy(d => d.id)
.Select(d => new
{
d.customer.name,
d.customer.address
})
.ToList();
CodePudding user response:
Why is deliveries.Include(d=>d.customer.name)
wrong?
according to docs, the included parameter is an related Entity, not an simple type. Find more about eager loading
The simplest way to solve:
dataGridView1.DataSource = dbContext.deliveries
.Include(x => x.customer)
.Select new(x =>
{
Id = x.id,
CustomerName = x.customer.name,
//more properties you want to display
})
.OrderBy(x => x.id).ToList();
Note:
- according to @Svyatoslav Danyliv the
Include
can be omitted. - Maybe you didn't paste your actual code, but classes and properties should follow good naming convension.