Ответы пользователя по тегу Entity Framework
  • Как правильно сделать выборку из БД, используя Entity Framework?

    @AIgin
    Проблема в том, что запрос возвращает объекты анонимного класса, а при добавлении и изменении передаётся класс Product. Для решения проблемы есть два варианта:
    1. Полученные данные из анонимного класса преобразовать в Product
    productBindingSource.DataSource = products.AsEnumerable().Select(a => new Product() { id = a.id, name = a.name, price = a.price, Menu = new Menu(){ name = a.Menu.name });

    AsEnumerable() (можно использовать ToList()) вызывается для выполнения запроса, без него будете получать Exception, т.к. EF не сможет разобрать такой Select().
    2. Добавляемые и изменяемые данные преобразовывать из Product в анонимный класс
    productBindingSource.Add(
                        new
                        {
                            frm.ProductInfo.id,
                            frm.ProductInfo.name,
                            frm.ProductInfo.price,
                            Menu = frm.ProductInfo.Menu.name
                        });;


    Но следует учесть, что для добавления в БД новых записей через EF всё равно придётся потом приводить данные к классам из модели (Product)
    Ответ написан
    Комментировать
  • Как получить данные из связанной таблицы Entity Framework?

    @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 }
                    });
            }
        }
    }


    В описанном вами случае ни ленивая загрузка, ни прокси-классы не мешают получать требуемый результат и конфигурацию по-умолчанию можно не менять.
    Ответ написан
    Комментировать
  • Как исправить ошибку в EntityModel?

    @AIgin
    Как писал Константин Косьянов, если нет дополнительных настроек связей (например, через Fluent API), то EF следует соглашению об именовании внешних ключей, которому приведённый код не соответствует. В этом случае необходимо добавить атрибут ForeignKey с именем соответствующего навигационного свойства:
    [ForeignKey("Doctors")]
    public int idDoctor { get; set; }
    Ответ написан
    Комментировать