Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
Подскажите люди добрые такой вопрос ( может кто встречался)
Есть модель:
public class WeightNorm
    {
        public int ID { get; set; }
        public int? statBeginID { get; set; }
        public int? statEndID { get; set; }
        public int? tlID { get; set; }
        public int? areaID { get; set; }
        public int wnNorma { get; set;}
        public TypeLoko tl { get; set; }
        public Station statBegin { get; set; }
        public Station statEnd { get; set; }
        public Area area { get; set; }
    }

и модель:
public class Station
    {
        public int ID { get; set; }
        public string statName { get; set; }
        public int? areaID { get; set; }
        public Area Area { get; set; }
        public ICollection<WeightNorm> WeightNorms { get; set; }
        public Station()
        {
            WeightNorms = new List<WeightNorm>();
        }
    }

как вы наверно заметили, поле statBeginID и statEndID ссылаются на ID модели Station.
Для чего это сделано? Station - хранит станции. statBeginID-это станция отправления локомотива statEndID-станция прибытия локомотива. Так вот как мне связать эти таблицы?
Вот контроллер:
public ActionResult Index()
        {
            var norms = db.WeightNorms.Include(p => p.area).Include(p => p.statBegin).Include(p => p.statEnd).Include(p=>p.tl);
            return PartialView(norms.ToList());
        }

и тут ошибка:
SqlException: Недопустимое имя столбца "Station_ID".

Как мне это исправить?
16 май 19, 04:56    [21885805]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Тебе надо cконфигурировать навигационные свойства в методе контекста OnModelCreating. Что-то наподобие:

protected override void OnModelCreating(DbModelBuilder builder)
{
    builder.Entity<WeightNorm>()
        .HasOne(x => x.statBegin)
        .WithMany(x => x.WeightNorms);

    builder.Entity<WeightNorm>()
        .HasOne(x => x.statEnd)
        .WithMany(x => x.WeightNorms);
}
16 май 19, 07:02    [21885818]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
fkthat
 protected override void OnModelCreating(DbModelBuilder builder)
{
    builder.Entity<WeightNorm>()
        .HasOne(x => x.statBegin)
        .WithMany(x => x.WeightNorms);

    builder.Entity<WeightNorm>()
        .HasOne(x => x.statEnd)
        .WithMany(x => x.WeightNorms);
} 
ругается на .HasOne(x => x.statBegin) :(
16 май 19, 12:42    [21886122]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
Hanuman,
Возьмите любой пример один ко многим с FK.
И отработайте его чтоб работало.
...
Поле statBeginID лишнее. Есть поле класса.
16 май 19, 12:51    [21886128]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman
ругается на .HasOne(x => x.statBegin) :(

Мне сейчас без интеллисенса вспомнить точный вызов тяжело, поизучай вот это: https://docs.microsoft.com/en-us/ef/core/modeling/relationships - там все описано.
16 май 19, 13:17    [21886170]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
Petro123
Поле statBeginID лишнее. Есть поле класса.
Не совсем понял, почему это поле лишнее? А тогда поле statEndID тоже лишнее?
16 май 19, 15:28    [21886380]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
Hanuman,
Угу.
16 май 19, 15:32    [21886386]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman
Petro123
Поле statBeginID лишнее. Есть поле класса.
Не совсем понял, почему это поле лишнее? А тогда поле statEndID тоже лишнее?


Вообще, можно и так и так. Раньше то ли требовалось (то ли просто было принято - уже не помню) дублировать навигационные свойства айдишниками ентитей на которые они указывают. Сейчас это необязательно, есть, в общем-то сторонники такого подхода (иногда это позволяет некоторые дела ускорить). Лично мне эта избыточность не нравится, ибо POCO, коде-ферст и бла-бла-бла. К тому же (не уверен насчет обычного EF) в ефкоре это доступно через т.н. Shadow Properties (это поля БД, которые доступны, но не отмепленны на свойства объекта).
16 май 19, 15:53    [21886405]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman,

Сейчас попробовал (EF Core) смотри, тут есть еще такая засада, что есть ограничение - одно свойство, в этом случае
public ICollection<WeightNorm> WeightNorms { get; set; }

не может учавствовать сразу в двух отношениях (ну, это, типа ЕФ так себя ведет). Так что надо либо его вообще убрать и работать только через свойства statBegin, statEnd и делать так:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<WeightNorm>()
        .HasOne(x => x.statBegin)
        .WithMany()
        .IsRequired(false)
        .HasForeignKey(x => x.statBeginID);

    modelBuilder.Entity<WeightNorm>()
        .HasOne(x => x.statEnd)
        .WithMany()
        .IsRequired(false)
        .HasForeignKey(x => x.statEndID);
}


, либо заводить два разных WeightNorms:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<WeightNorm>()
        .HasOne(x => x.statBegin)
        .WithMany(x => x.WeighNormsBegin)
        .IsRequired(false)
        .HasForeignKey(x => x.statBeginID);

    modelBuilder.Entity<WeightNorm>()
        .HasOne(x => x.statEnd)
        .WithMany(x => x.WeighNormsBegin)
        .IsRequired(false)
        .HasForeignKey(x => x.statEndID);
}



Ни в том, ни в другом случае на структуру самой БД это не повлияет.
16 май 19, 16:23    [21886437]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Во втором куске кода, там конечно,

.WithMany(x => x.WeighNormsBegin)


и

.WithMany(x => x.WeighNormsEnd)
16 май 19, 16:25    [21886438]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
fkthat
public ICollection<WeightNorm> WeightNorms { get; set; }
Как я понял в первом варианте в модели я это удаляю.
тогда у меня модель останется:
public class Station
    {
        public int ID { get; set; }
        public string statName { get; set; }
        public int? areaID { get; set; }
        public Area Area { get; set; }       
        public Station()
        {
            WeightNorms = new List<WeightNorm>();
        }
    }
public class WeightNorm
    {
        public int ID { get; set; }
        public int? statBeginID { get; set; }
        public int? statEndID { get; set; }
        public int? tlID { get; set; }
        public int? areaID { get; set; }
        public int wnNorma { get; set;}
        public TypeLoko tl { get; set; }
        public Station statBegin { get; set; }
        public Station statEnd { get; set; }
        public Area area { get; set; }
    }

Ну и естественно код который вы предложили.
Насчет использования
 public int? statBeginID { get; set; }
        public int? statEndID { get; set; }

Это может быть и лишнее, но на данный момент мне так проще, я вижу все поля своих таблиц, и мне как новичку это удобно. В моем коде если вы его посмотрите, многое можно оптимизировать, что то лишнее, что то можно было более компактно описать :) так что не судите строго за "кривой код" :) за все советы спасибо :) завтра буду тестировать, и отпишусь о результатах :)
16 май 19, 19:11    [21886588]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman,

да, только

WeightNorms = new List<WeightNorm>();


убери еще, а то ошибка будет.
16 май 19, 19:13    [21886589]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman,

Чем неудобны доп. поля с айдишкаим - они при изменении сущности могут рассинхронизироваться с указателями.
16 май 19, 19:16    [21886591]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
fkthat
Чем неудобны доп. поля с айдишкаим - они при изменении сущности могут рассинхронизироваться с указателями.
Получается в самой БД эти поля тоже не нужны?
17 май 19, 05:42    [21886763]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
Собственно вот так у меня заработало:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<WeightNorm>()
                .HasOptional(x => x.statBegin)
                .WithMany()                
                .HasForeignKey(x => x.statBeginID);

            modelBuilder.Entity<WeightNorm>()
                .HasOptional(x => x.statEnd)
                .WithMany()                
                .HasForeignKey(x => x.statEndID);
        }

На HasOne у меня ругался, возможно моя версия EF это не поддерживает.
.IsRequired(false) - тоже начал ругаться, просто удалил ( может я не прав поправьте меня)
Спасибо Вам товарищи что помогли разобраться :) Эта наверно не последняя моя тема с просьбой помочь, так что буду Вам рад :)
17 май 19, 06:16    [21886766]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman
fkthat
Чем неудобны доп. поля с айдишкаим - они при изменении сущности могут рассинхронизироваться с указателями.
Получается в самой БД эти поля тоже не нужны?

Нет, в БД они конечно нужны (иначе как EF посвязывает эти сущности). Просто при code first они автоматом создадутся в миграции, при db first нужен будет дополнительный fluent вызов чтобы дать EF понять какое поле в БД отвечает за эту связку.
17 май 19, 06:42    [21886773]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman
Собственно вот так у меня заработало:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<WeightNorm>()
                .HasOptional(x => x.statBegin)
                .WithMany()                
                .HasForeignKey(x => x.statBeginID);

            modelBuilder.Entity<WeightNorm>()
                .HasOptional(x => x.statEnd)
                .WithMany()                
                .HasForeignKey(x => x.statEndID);
        }

На HasOne у меня ругался, возможно моя версия EF это не поддерживает.
.IsRequired(false) - тоже начал ругаться, просто удалил ( может я не прав поправьте меня)
Спасибо Вам товарищи что помогли разобраться :) Эта наверно не последняя моя тема с просьбой помочь, так что буду Вам рад :)


Да, я пробовал на EF Core - там немного по-другому. Но, вообще, мне кажется, что EF Core и так бы заработал, на основе conventions - он по-умолчанию если видит указатель от одной entity к другой, то связывает их по FK базы данных.
17 май 19, 06:46    [21886775]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
Вот еще вопрос, к теме не относится, но я его задам что бы не создавать новую тему :)
В модели есть поля:
 public decimal waDistancia { get; set; }
        public decimal waSCC { get; set; }
        public decimal waReserv { get; set; }

База создавалась вот так:
 [waDistancia]  DECIMAL (5, 2) DEFAULT (NULL) NULL,
    [waSCC]        DECIMAL (5, 2) DEFAULT (NULL) NULL,
    [waReserv]     DECIMAL (5, 2) DEFAULT (NULL) NULL,

у меня допускается значение NULL, но вылазит ошибка

The 'waSCC' property on 'WorkArea' could not be set to a 'null' value. You must set this property to a non-null value of type 'System.Decimal

Почему то ругается на нулевые поля.
17 май 19, 07:22    [21886788]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
Тут наверно нужно использовать все таки
IsRequired() , но у меня на него почему то ругается.... Может опять из за версии EF :)
17 май 19, 07:27    [21886790]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Hanuman,

public decimal? waDistancia { get; set; }
public decimal? waSCC { get; set; }
public decimal? waReserv { get; set; }


для nullable полей БД надо свойства модели тоже объявлять как nullable, имхо, это даже интуитивно должно быть очевидно.
17 май 19, 08:17    [21886801]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Hanuman
Member

Откуда:
Сообщений: 29
fkthat
Вот моя не внимательность :)
17 май 19, 15:41    [21887413]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
Так а я не понял - почему у ТС не работает код из первого примера?

У него же всё правильно (почти).


Petro123
Поле statBeginID лишнее. Есть поле класса.

Что это значит??
19 май 19, 11:48    [21888107]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
fkthat
Member

Откуда:
Сообщений: 1611
Агнец за бортом
Так а я не понял - почему у ТС не работает код из первого примера?

Потому что отношение было ен сконфигурировано. Там же ниже все расписано.
19 май 19, 12:14    [21888124]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
fkthat
Агнец за бортом
Так а я не понял - почему у ТС не работает код из первого примера?

Потому что отношение было ен сконфигурировано. Там же ниже все расписано.


Ты про Fluent API?

Это для какой EF?

Для EF 6 - Fluent API - опция, выбор.


Того, что сделал ТС - должно быть достаточно.

И потом - SqlException - не про "отношение было ен сконфигурировано"

Может быть - он пытается создать БД, не уничтожив предыдущую?
19 май 19, 12:30    [21888136]     Ответить | Цитировать Сообщить модератору
 Re: Модель со связанными таблицами  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
Агнец за бортом
Что это значит??

это оверхед.
В коде можно и нужно работать через поле класса сущности, а не через поле ID сущности.
Кодами FK занимается ОРМ.
19 май 19, 15:23    [21888211]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Ответить