Задать вопрос

Как получить данные из связанной таблицы Entity Framework?

Есть следующая БД
29a3e091375c4256810a9bbae420bed1.png
нужно получить следующие данные {bid.id, bid.text, bid.datetime_created, user_created_name, user_executor_name}
делаю так
dbContext = new Model1(); модель базы CodeFirst
dbContext.BID.Load();
var bid = dbContext.BID.Local;
bindingSource1.DataSource = bid.ToBindingList();
dataGridView1.DataSource = bindingSource1;


Всё выводится, но вместо данных из связной таблицы "System.Data.Entity.DynamicProxies. ..." , на сколько я понимаю это из за LazyLoad.
Если отключить LazyLoad вот так
dbContext.Configuration.LazyLoadingEnabled = false;
то вообще ничего не выводится.

Подскажите что написать чтоб данные подгружались из связанных таблиц ?
  • Вопрос задан
  • 3641 просмотр
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 4
DarkRaven
@DarkRaven
разработка программного обеспечения
Примерно так, непонятно какой там у вас контекст.
using(var db = new Model1())
{
	var data = (from bid in db.BID 
	           join u_c in db.Users on u_c.id = bid.user_id_created
			   join u_e in db.Users on u_e.id = bid.user_id_executor
			   select new BIDDto
			   {
				   id = bid.id, 
				   text = bid.text, 
				   datetime_created = bid.datetime_created, 
				   user_created_name = u_c.Name, 
				   user_executor_name = u_e.Name
			   }).ToArray();
    /// Дальше помещайте data куда нужно
}


BIDDto это класс с нужными вам полями.
Ответ написан
Комментировать
@AIgin
В вашем случае код для Code-First будет выглядеть примерно так:
[Table("Role")]
public class Role
{
    [Column("id"), Key]
    public int Id { get; set; }

    [Column("name"), Required]
    public string Name { get; set; }
}

[Table("User")]
public class User
{
    [Column("id"), Key]
    public int Id { get; set; }

    [Column("name"), Required]
    public string Name { get; set; }

    [Column("password"), Required]
    public string Password { get; set; }

    [Column("role_id"), ForeignKey("Role")]
    public int RoleId { get; set; }

    public virtual Role Role { get; set; }

    [InverseProperty("Creator")]
    public virtual List<Bid> BidsWhereUserAsCreator { get; set; }

    [InverseProperty("Executor")]
    public virtual List<Bid> BidsWhereUserAsExecutor { get; set; }
}

[Table("bid")]
public class Bid
{
    [Column("id"), Key]
    public int Id { get; set; }

    [Column("Text"), Required]
    public string Text { get; set; }

    [Column("DateTime_Created")]
    public DateTime Created { get; set; }

    [Column("user_id_created"), ForeignKey("Creator")]
    public int CreatorId { get; set; }

    [Column("user_id_executor"), ForeignKey("Executor")]
    public int ExecutorId { get; set; }

    public virtual User Creator { get; set; }

    public virtual User Executor { get; set; }
}

public class MyDbContext : DbContext
{
    public virtual DbSet<Role> Roles { get; set; }

    public virtual DbSet<User> Users { get; set; }

    public virtual DbSet<Bid> Bids { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // убираем каскадное удаление
        // http://stackoverflow.com/questions/17127351/introducing-foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    }

    public static void Test()
    {
        using (MyDbContext dbContext = new MyDbContext())
        {
            // говорим, что не надо создавать динамически генерируемые прокси-классы
            // (которые System.Data.Entity.DynamicProxies...)
            dbContext.Configuration.ProxyCreationEnabled = false;
            // отключаем ленивую загрузку
            dbContext.Configuration.LazyLoadingEnabled = false;

            // поля класса будут заполнены, но данные навигационных свойств загружены не будут.
            List<Bid> bidsOnly = dbContext.Bids.ToList();

            // поля навигационных свойств можно загрузить через Include
            List<Bid> bidsWithAllInfo = dbContext.Bids.Include(b => b.Creator).Include(b => b.Executor).Include(b => b.Creator.Role).Include(b => b.Executor.Role).ToList();

            // данные для навигационного поля Creator будут загружены автоматически
            IEnumerable<Bid> bids = dbContext.Bids.Include(b => b.Executor).Where(b => b.Creator.RoleId == 1).ToList().Select(
                b => new Bid()
                {
                    Id = b.Id,
                    Text = b.Text,
                    Created = b.Created,
                    Creator = new User() { Name = b.Creator.Name },
                    Executor = new User() { Name = b.Executor.Name }
                });
        }
    }
}


В описанном вами случае ни ленивая загрузка, ни прокси-классы не мешают получать требуемый результат и конфигурацию по-умолчанию можно не менять.
Ответ написан
Комментировать
Используйте Include()
Ответ написан
Комментировать
@kttotto
пофиг на чем писать
Немного странный код Вы привели. А можно увидеть код Вашего dbContext?

Если Вы используете codfirst, то таблицы связываются настройкой модели через создание виртуальных свойств у модели с указанием внешних ключей и при необходимости настраиваются атрибутами или Fluent API. Тогда данные будут подтягиваться автоматом dbContext.Bid.UserCreated.Id
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы