Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# ASP.NET MVC
Войти
Регистрация
Восстановить пароль
 
darkmesser
0 / 0 / 1
Регистрация: 04.11.2013
Сообщений: 148
#1

Связь между моделями - C# MVC

21.11.2015, 16:43. Просмотров 916. Ответов 6
Метки нет (Все метки)

Есть модель Product, Category и FilePath (содержит путь к картинке). Product может иметь картинку(FilePath), и каждная Category может иметь картинку.
Как организовать связи между моделями? Может, в табице FilePath нужно сделать две колонки, которые nullable, то есть в картинки может быть или Product, или Category?

1. Как реализовать такую связь?
2. Если в Product может быть много картинок, а в Category только одна (получается один ко многим, а другая один к одному), как реализовать такую связь?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.11.2015, 16:43
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Связь между моделями (C# MVC):

Как можно задать между двумя сущностями связь многие ко многим с code first
есть два класса пользователь и автомобиль. Как можно задать между ними связь...

Связь между моделями 1 к 1 в CodeFirst
Создаю базу FirstCode. Многое перепробовал, связь остается 1 ко многим. Как...

Связь между двумя контролами на разных страницах
Здравствуйте. Собственно, имеется 2 контрола GridView на двух разных...

Связь между таблицами в Access и разделение информации
Есть первая таблица связывающая названия разделов информации (разделов сайта,...

Создать две таблицы (продукт, и производитель), и создать между ними связь — один ко многим
Всем привет. Появилась проблема. Нужно создать две таблицы (продукт, и...

Робота с моделями со сложной структурой в контроле
Есть 3 таблицы в бд и 3 модели для них, в таблиц связь Song->Album->Artist (В...

6
IamRain
1279 / 1171 / 360
Регистрация: 02.08.2011
Сообщений: 3,416
22.11.2015, 09:11 #2
Product - FilePath (1 - m),
Category - FilePath (1-1..0)
С EF CodeFirst это будет выглядеть так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class Product
    {
       public int ProductId { get; set; }
       public string ProductName { get; set; }
 
       public virtual IList<FilePath> FilePaths { get; set; }
       
       public Product()
       {
           FilePaths = new List<FilePath>();
       }        
    }
 
 
    public class FilePath
    {
        public int FilePathId { get; set; }
        
        public int ProductId {get;set;}
 
        public int CategoryId {get;set;}
 
        public string Path { get; set; }
 
        public virtual Product Product { get; set; }
 
        public  virtual  Category Category { get; set; }        
    }
 
 
    public class Category
    {
        public int CategoryId { get; set; }
 
        public string CategoryName { get; set; }
 
        public virtual FilePath Path { get; set; }      
 
    }
      
   public class MyContext: DbContext
    {
 
        public MyContext()
            : base("UrConnectionStringNameFromConfigFile")
        {
            Products = Set<Product>();
            Categories = Set<Category>();
        }
 
 
        public IDbSet<Product> Products { get; set; }
        public IDbSet<Category> Categories { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {   
            base.OnModelCreating(modelBuilder);
            modelBuilder.Configurations.Add(new CategoryConfiguration());
            modelBuilder.Configurations.Add(new FilePathConfiguration());
            modelBuilder.Configurations.Add(new ProductConfiguration());
        }
    }
 
public class ProductConfiguration : EntityTypeConfiguration<Product>
    {
        public ProductConfiguration()
        {
            ToTable("Products");
            HasMany(x => x.FilePaths).WithRequired(x => x.Product).HasForeignKey(x => x.ProductId);
        }
    }
    public class FilePathConfiguration : EntityTypeConfiguration<FilePath>
    {
        public FilePathConfiguration()
        {
            ToTable("FilePaths");
        }
    }
 
    public class CategoryConfiguration : EntityTypeConfiguration<Category>
    {
        public CategoryConfiguration()
        {
            ToTable("Categories");
            HasOptional(x=>x.Path).WithRequired(x=>x.Category).WillCascadeOnDelete(true);
        }
    }
Добавлено через 9 минут
Просто у таблицы с файлами будет две связи: 1 ко многим (с продуктами) , и один к одному (с категориями).

Добавлено через 30 минут
Цитата Сообщение от darkmesser Посмотреть сообщение
Может, в табице FilePath нужно сделать две колонки, которые nullable, то есть в картинки может быть или Product, или Category?
Если продукт имеет картинку (изображение продукта), и также категория имеет картинку (какое-то обобщенное отображение товаров), то значит одна и та же сущность картинки (FilePath) не может быть одновременно картинкой и для товара, и для категории - такова семантика. Поэтому отсюда две связи. И два nullable поля здесь не нужно.

Добавлено через 10 минут
Хотя нет, фигню сказал , как раз таки надо будет два поля - в модели ведь уже отображено.
С тем исправлением, что они должны быть nullable, все верно.

Добавлено через 3 минуты
Конфигурации, соответственно будут такими:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class CategoryConfiguration : EntityTypeConfiguration<Category>
    {
        public CategoryConfiguration()
        {
            ToTable("Categories");
            HasOptional(x=>x.Path).WithOptionalPrincipal(x=>x.Category);
        }
    }
 
public class ProductConfiguration : EntityTypeConfiguration<Product>
    {
        public ProductConfiguration()
        {
            ToTable("Products");
            HasMany(x => x.FilePaths).WithOptional(x=>x.Product).HasForeignKey(x => x.ProductId);
        }
    }
Добавлено через 11 часов 47 минут
А, не, с EF при отношении 1-1 не получится сделать чтобы внешний ключ зависимой таблицы был nullable.
Потому что при Code First подходе для связи 1-1 EF требует, чтобы PK зависимой таблицы одновременно являлся и FK. - а PK не может быть равен null.
C Code First я не знаю как такое сделать. Можно поискать какие-нибудь ухищрения.

Добавлено через 8 минут
Вот при такой конфигурации:
Кликните здесь для просмотра всего текста
p
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ublic class ProductConfiguration : EntityTypeConfiguration<Product>
    {
        public ProductConfiguration()
        {
            ToTable("Products");
            HasMany(x => x.FilePaths).WithOptional(x=>x.Product).HasForeignKey(x => x.ProductId);
        }
    }
    public class FilePathConfiguration : EntityTypeConfiguration<FilePath>
    {
        public FilePathConfiguration()
        {
            ToTable("FilePaths");
            HasRequired(x => x.Category).WithOptional(x => x.Path);
        }
    }
 
    public class CategoryConfiguration : EntityTypeConfiguration<Category>
    {
        public CategoryConfiguration()
        {
            ToTable("Categories");
        }
    }

Получается вот такое:
0
IamRain
1279 / 1171 / 360
Регистрация: 02.08.2011
Сообщений: 3,416
22.11.2015, 09:15 #3
0
Миниатюры
Связь между моделями  
Metall_Version
2116 / 1253 / 516
Регистрация: 04.03.2014
Сообщений: 4,094
Завершенные тесты: 2
22.11.2015, 11:38 #4
Цитата Сообщение от IamRain Посмотреть сообщение
А, не, с EF при отношении 1-1 не получится сделать чтобы внешний ключ зависимой таблицы был nullable.
Потому что при Code First подходе для связи 1-1 EF требует, чтобы PK зависимой таблицы одновременно являлся и FK. - а PK не может быть равен null.
Но можно сделать PK зависимой таблицы (B) как FK который ссылается на PK главной таблицы (A), связь ведь не обязывает что всегда должна быть запись в таблице B на каждую запись в таблице A. Но наоборот должно быть всегда, Если есть запись в таблице B то должна быть связанная запись в таблице А, на которую мы ссылаемся из таблицы B.
Этот тип связи называется One-to-Zero-or-One

http://stackoverflow.com/questions/1...ork-code-first
1
IamRain
1279 / 1171 / 360
Регистрация: 02.08.2011
Сообщений: 3,416
22.11.2015, 14:10 #5
Metall_Version, спасибо, просто сам себя запутал.
В ответе из ссылки как раз пример из книги, по которой изучал Code First.

Добавлено через 1 час 11 минут
Хотя не, поторопился благодарить.
Цитата Сообщение от Metall_Version Посмотреть сообщение
Этот тип связи называется One-to-Zero-or-One
1)Это будет работать в отношении Category - Filepath.
То есть я могу создать родительскую запись в Category, и могу создать дочернюю запись, а могу и не создавать.
Если создам, то FK productId в дочерней записи будет равен null. Так и нужно.
2) Но есть еще второе отношение Product - FilePath (one-to-many).
Если я создаю, объект Product, добавляю к нему три дочерние записи FilePath:
C#
1
2
3
4
5
6
7
8
var product = new Product(){FilePaths =
                {
                    new FilePath(){Path = "First"},
                    new FilePath(){Path = "Second"},
                    new FilePath(){Path = "Third"}
                }};
                context.Products.Add(product);
                context.SaveChanges();
То должно быть так, чтобы эти три дочерние записи не имели никакого отношения к любой записи из таблицы Categories. Но поскольку PK не могут быть равными null, то получается они автоматически привязываются к каким-то объектам Category. По сути нужно one-to-zero-or-one только в противоположную сторону - что невозможно.
Нельзя создать дочернюю таблицу одновременно в обоих отношениях (1-1 или 1-0..1 и 1-m) у который два FK будут поддерживать null-значение, поскольку в отношении 1-1 Code First требует чтобы FK был также PK. - Окончательный ответ.

Добавлено через 50 минут
darkmesser, создавайте 1-m и 1-0..1 связи в любом предназначенном для этого редакторе, типа Management Studio.
0
Metall_Version
2116 / 1253 / 516
Регистрация: 04.03.2014
Сообщений: 4,094
Завершенные тесты: 2
22.11.2015, 15:41 #6
Цитата Сообщение от IamRain Посмотреть сообщение
1)Это будет работать в отношении Category - Filepath.
То есть я могу создать родительскую запись в Category, и могу создать дочернюю запись, а могу и не создавать.
Если создам, то FK productId в дочерней записи будет равен null. Так и нужно.
я не про данный конкретный случай, а про ваше сообщение что EF нельзя создать такую связь, я показал пример как можно сделать такой вид связи в EF

для такой связи (1-1 или 1-0..1) внешний ключ должен быть также первичным, для внешней таблицы.
в данной модели Category - Filepath такого не наблюдается, у них связь 1-m, поэтому про такие связи говорить даже не нужно.
0
darkmesser
0 / 0 / 1
Регистрация: 04.11.2013
Сообщений: 148
23.11.2015, 21:10  [ТС] #7
Спасибо за Ваше время.
Я делаю интернет магазин. У меня есть категории(Компьютеры, Телевизоры) и подкатегории(Ноутбуки, LED телевизоры). Идея такая, что, когда юзер кликает на Компьютер, ищем все категории у которых ParеntId ровно ComputerId и показываем названия подкатегорий и их фото.
Также есть товары, которые могут иметь много фото. Одно фото будет иметь свойство IsMain, которое показывает, что фото нужно выводить как главное, а остальные (не IsMain) можно посмотреть при детальном просмотре товара.
Я так понял для категорий лучше сделать поле string ImagePath, а для товаров 1-n.
0
23.11.2015, 21:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.11.2015, 21:10
Привет! Вот еще темы с решениями:

Как отобразить сборное представление с двумя моделями?
Вопрос написан сумбурно, объясню подробнее. У меня есть мастер страница, у...

Связи между моделями
Всем добрый день. Не знал куда написать, поэтому решил сначала сюда. Весь...

Выбор между 3 моделями
Добрый день. Выбираю себе недорогой ноутбук для интернета, видео в 480p,...

Связи между моделями в Yii2
Доброй ночи. Столкнулся с проблемой, есть 2 тестовые связаные таблицы в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru