AminTN
AminTN

Reputation: 110

Prevent a data grid from loading Entity Framework navigation properties in C#

I have a database (Firebird to be specific, but I believe the issue is something to do with EF). I have generated the code files using Code First from Database. The code generated for example for a Driver is:

[Table("Firebird.DRIVER")]
public partial class DRIVER
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public DRIVER()
    {
        FAREs = new HashSet<FARE>();
    //..... and other code generated for the other collections
    }


    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int DRIVERID { get; set; }

    [StringLength(100)]
    public string FULLNAME { get; set; }
    //... and other properties


    public int? EQUIPMENTID { get; set; }

    public virtual EQUIPMENT EQUIPMENT { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<FARE> FAREs { get; set; }
    //.... and other code generated for the other collections

 }

I have a basic form with a DataGridView. The purpose of the DataGridView is to edit, add or delete new entities (Drivers). I bind it this way

    private async Task BindGrid()
    {
        var DBContext = AppVariables.CreateContext();
        await Task.Run(() => DBContext.DRIVERs.Load());
        var bindingSource = DBContext.DRIVERs.Local.ToBindingList();
        dataGridView1.DataSource = bindingSource;
    }

However, I get in my grid the navigation properties (for example EQUIPMENT). What can I do to remove the navigation properties from loading in the grid. Should I delete the navigation property from code first? Or is there another way to load the data into the grid without loading the navigation properties?

I have tried to create objects using only the properties and avoiding the navigation one but the grid wouldn't be editable

    private async Task BindGrid()
    {
        var list = from driver in DBContext.DRIVERs
                   select new
                   {
                       DRIVERID = destination.DRIVERID
                       //...
                   };
        await list.LoadAsync();
        var bindingSource = list.ToBindingList();
        dataGridView1.DataSource = bindingSource;
    }

Upvotes: 4

Views: 795

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125277

Loading navigation properties and showing them are two different topics.

Prevent Loading

Disable lazy loading and just include those navigation properties which you need

var db = new MyDbContext(); 
db.Configuration.LazyLoadingEnabled = false; 
data = db.MyEntity.Local.ToBindingList();

Prevent Showing

Decorate the navigation property by [Browsable(false)].

[Browsable(false)]
public virtual EQUIPMENT EQUIPMENT { get; set; }

Or

Set the column visibility to false:

dataGridView1.Columns["EQUIPMENT"].Visible = false

Or

At the first place, define just a set of columns which you want for your DataGridView using designer or using code. Then DataGridView will show just those columns which you defined:

var DRIVERIDColumn = new DataGridViewTextBoxColumn();
DRIVERIDColumn.Name = "DRIVERID";
DRIVERIDColumn.HeaderText = "Id";
DRIVERIDColumn.DataPropertyName= "DRIVERID";
// ...
dataGridView1.Columns.AddRange(DRIVERIDColumn /*...*/);
// ...

Upvotes: 3

Related Questions