Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / c# фабрика классов EF Code First / 17 сообщений из 17, страница 1 из 1
06.11.2014, 08:23
    #38796929
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Здравствуйте.

Подскажите пожалуйста, как правильно реализовать фабрику классов в EF.

Описание доменной структуры EF Code First:

Имеется класс Main, в котором реализована связь один ко многим к классам A B C.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public class Main
{
     [Key]
     public int Id { get; set; }
     public string  Name { get; set; }

     // Связи с классами A B C  
     public virtual ICollection<A> As{ get; set; }
     public virtual ICollection<B> Bs{ get; set; }
     public virtual ICollection<С> Cs{ get; set; }

     // Нужно реализовать в одном методе ли свойстве вывод набора данных As, Bs, Cs
     // public Fabric_A_B_C 
 
}


Классы с ForeingKey
Код: 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.
public class A
{   
     [Key] 
     public int Id { get; set; }
     public string Name { get; set; }

     public int IdMain { get; set; } // Foreing Key
     public Main Main { get; set; }
}
public class B
{   
     [Key] 
     public int Id { get; set; }
     public string Adress{ get; set; }

     public int IdMain { get; set; } // Foreing Key
     public Main Main { get; set; }
}
public class C
{   
     [Key] 
     public int Id { get; set; }
     public bool Status { get; set; }

     public int IdMain { get; set; } // Foreing Key
     public Main Main { get; set; }
}



Теперь собственно говоря сам вопрос.
Как реализовать вывод свойств ICollection (As, Bs, Cs) класса Main, через один общий метод или свойство?

Нормально объяснил?
...
Рейтинг: 0 / 0
06.11.2014, 12:18
    #38797155
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
нет... вопрос и задача неясны... приведенный пример наводит на печальные мысли... фабрика как-то выбивается из примера(задачи)...
абстрактный класс интерфейс...? почитать про наследование(inheritance) в (with) EF [Code First]?...
...
Рейтинг: 0 / 0
11.11.2014, 12:42
    #38801885
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Почитал как вы говорили про наследования. Но вопрос все равно остался.

Постараюсь еще раз объяснить суть задачи, со стороны интерфейса.

Имеется два DataGridView:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 - Первый DataGridView, он же основной. Выводит к примеру каталог разных запчастей на автомобиль. 
                                        Структура полей в данном таблице общая для всех типов запчастей.
                                        (Артикул( Primery Key ), Название).
                                        ItemSourse = привязка к классу Main.
                                         
 - Второй DataGridView вспомогательный. Он предназначен для вывода подробной информации исходя из выбранной позиции в первом DataGridView.
                                        Наборы данных, которые выводятся в DataGridView:
                                        объявлены в классе Main
                                        public virtual ICollection<A> As{ get; set; }
                                        public virtual ICollection<B> Bs{ get; set; }
                                        public virtual ICollection<С> Cs{ get; set; }
                                        
                                        В итоге, чтобы отображалась информация во втором DataGridView, нужно биндить к ItemSourse одну из ICollection (As или Bs или Cs). 
                                        Что не позволяет, мне в DataGridView выводить информацию по любому ICollection, не выполнив
                                        очередной бинд к ItemSourse.
   

Задача, которую я пытаюсь решить заключается: как при помощи одного биндинга , выводить информацию во второй DataGridView, любой из трех ICollection?
ItemSourse = " As_Bs_Cs "
...
Рейтинг: 0 / 0
11.11.2014, 12:48
    #38801898
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Nechto,

А как понять что выводить во второго гриде: все А, все B, или все С? На основе чего такой вывод делается? Ведь в каждой записи Main есть все три коллекции?
...
Рейтинг: 0 / 0
11.11.2014, 13:03
    #38801941
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
hVosttNechto,
А как понять что выводить во второго гриде: все А, все B, или все С?

Любая запись в Main, может имеет только одну из трех коллекций, остальные две будут пустые.
К примеру:

Код: plaintext
1.
2.
3.
4.
5.
ID   NAME   As   Bs    Cs

1    1111   null  {B}  null
2    2222   {A}  null  null
3    3333   {A}  null  null


hVosttNechto,
На основе чего такой вывод делается? Ведь в каждой записи Main есть все три коллекции?

Вот мне и надо сделать своего рода объединяющее свойство которое бы выводила коллекции в таком виде:
Код: plaintext
1.
2.
3.
4.
5.
ID   NAME   As_Bs_Cs

1    1111   {B}  
2    2222   {A}
3    3333   {A}
...
Рейтинг: 0 / 0
11.11.2014, 13:18
    #38801976
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Nechto,

А, тогда можно (и скорее всего даже нужно) реализовать это следующим образом:

1. Вместо одного Main класса, базовый MainBase и три наследника MainA, MainB, MainC
2. Каждый из наследников ссылается только на 1 свою коллекцию: As, Bs, Cs.
3. Берёшь из базы коллекцию MainBase и суёшь в первый грид.
4. Биндишь второй грид на вычисляемое свойство-коллекцию.

Пример:

Код: 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.
public abstract class Main
{
     [Key]
     public int Id { get; set; }
     public string  Name { get; set; } 

     public abstract ICollection<object> Foreigns { get; }
}

public class MainA : Main
{
     public virtual ICollection<A> As{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return As.Cast<object>(); }
     }
}

public class MainB : Main
{
     public virtual ICollection<B> Bs{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return Bs.Cast<object>(); }
     }
}

public class MainC : Main
{
     public virtual ICollection<С> Cs{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return Cs.Cast<object>(); }
     }
}




Классы с ForeingKey


Код: 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.
public class A
{   
     [Key] 
     public int Id { get; set; }
     public string Name { get; set; }

     public int IdMain { get; set; } // Foreing Key
     public MainA Main { get; set; }
}
public class B
{   
     [Key] 
     public int Id { get; set; }
     public string Adress{ get; set; }

     public int IdMain { get; set; } // Foreing Key
     public MainB Main { get; set; }
}
public class C
{   
     [Key] 
     public int Id { get; set; }
     public bool Status { get; set; }

     public int IdMain { get; set; } // Foreing Key
     public MainC Main { get; set; }
}



Маппишь второй грид к свойству Foregns.

Я без понятия что ты собрался выводить, и главное КАК, если A,B,C -- разные классы с разными набором свойств, так что и вывел object, может делать ToString хотябы. Незнаю в общем. Но суть такая.
...
Рейтинг: 0 / 0
11.11.2014, 14:33
    #38802143
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Может я что-то не понял.

Но при такой реализации, у меня теперь три Main для первого DataGridView. А нужен то один.
...
Рейтинг: 0 / 0
11.11.2014, 14:47
    #38802182
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
NechtoМожет я что-то не понял.

Но при такой реализации, у меня теперь три Main для первого DataGridView. А нужен то один.

Нет, один Main и три его наследника. Из EF получаешь Main:

Код: c#
1.
2.
3.
var mains = context.Mains.ToList();

// работаешь с mains, там лежат экземпляры-наследники: MainA, MainB, MainC



Добавляешь в базу конкретные Main:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
using(var context = new MyContext())
{
 
   var ma = new MainA { ... };
   context.Mains.Add(ma);

   var mb = new MainB { ... };
   context.Mains.Add(mb);

   ...
  
}



В общем, это самое простое решение. Кроме того, исходя из твоей задачи, что каждый Main должен содержать лишь одну из трёх коллекций, это самый очевидно правильный способ решения, так как технически не допускает ошибки, и ты точно знаешь, что у тебя за Main (A,B или C).
...
Рейтинг: 0 / 0
11.11.2014, 14:51
    #38802194
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
А этот пример, который вы привели выше, будет работать с Code First?
...
Рейтинг: 0 / 0
11.11.2014, 14:56
    #38802209
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
NechtoА этот пример, который вы привели выше, будет работать с Code First?

Именно.
...
Рейтинг: 0 / 0
12.11.2014, 06:42
    #38802934
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Спасибо за помощь, сейчас буду пробовать.
...
Рейтинг: 0 / 0
12.11.2014, 10:16
    #38803078
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Что то не выходи.

Делаю миграцию
Код: 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.
public partial class dsdsd : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.A",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Adress = c.String(maxLength: 100),
                        IdMain = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Katalog", t => t.IdMain, cascadeDelete: true)
                .Index(t => t.IdMain);
				
			CreateTable(
                "dbo.B",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Name = c.String(maxLength: 100),
                        IdMain = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Katalog", t => t.IdMain, cascadeDelete: true)
                .Index(t => t.IdMain);	
				
			CreateTable(
                "dbo.C",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Status = c.Boolean(),
                        IdMain = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Katalog", t => t.IdMain, cascadeDelete: true)
                .Index(t => t.IdMain);	
            
            CreateTable(
                "dbo.Katalog",
                c => new
                    {
                        UnionId = c.Int(nullable: false, identity: true),
                        Name = c.String(maxLength: 200),
                        Discriminator = c.String(nullable: false, maxLength: 128), // Откуда взялось это поле???
                    })
                .PrimaryKey(t => t.UnionId)
        }		
	}	




По этой структуре

Код: 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.
public abstract class Main
{
     [Key]
     public int Id { get; set; }
     public string  Name { get; set; } 

     public abstract ICollection<object> Foreigns { get; }
}

public class MainA : Main
{
     public virtual ICollection<A> As{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return As.Cast<object>().ToList(); }
     }
}

public class MainB : Main
{
     public virtual ICollection<B> Bs{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return Bs.Cast<object>().ToList(); }
     }
}

public class MainC : Main
{
     public virtual ICollection<С> Cs{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return Cs.Cast<object>().ToList(); }
     }
}




Почему-то генерируется это поле Discriminator.
...
Рейтинг: 0 / 0
12.11.2014, 11:15
    #38803160
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
NechtoПочему-то генерируется это поле Discriminator.

Всё верно, с помощью этого поля EF определяет что там MainA, MainB или MainC. Техническое поле, оно необходимо.
...
Рейтинг: 0 / 0
12.11.2014, 12:28
    #38803306
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Выходит что без этого поля не обойтись, я правильно понимаю.
...
Рейтинг: 0 / 0
12.11.2014, 13:39
    #38803442
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
NechtoВыходит что без этого поля не обойтись, я правильно понимаю.

Без дополнительного поля нет. EF с помощью этого поля реализует наследование. Тебе-то какая разница? Ну добавилось поле, от этого ни жарко, ни холодно. Зато задача решена.

Если есть сильное желание, можно изменить тип и название этого поля, но обычно это нафиг не нужно.
...
Рейтинг: 0 / 0
12.11.2014, 14:12
    #38803516
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
hVosttNechtoВыходит что без этого поля не обойтись, я правильно понимаю.

Без дополнительного поля нет. EF с помощью этого поля реализует наследование. Тебе-то какая разница? Ну добавилось поле, от этого ни жарко, ни холодно. Зато задача решена.

Если есть сильное желание, можно изменить тип и название этого поля, но обычно это нафиг не нужно.

НУ так то оно так. Спасибо за грамотное решения задачи.

Вот еще поделюсь своим первым вариантом, который я сделал до открытия этой темы. Так для полноты темы.
Код: 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.
public class Main
{
     [Key]
     public int Id { get; set; }
     public string  Name { get; set; }

     // Связи с классами A B C  
     public virtual ICollection<A> As{ get; set; }
     public virtual ICollection<B> Bs{ get; set; }
     public virtual ICollection<С> Cs{ get; set; }

     // Мое первое решение
     [NotMapped]
     public virtual ICollection<object> Foreigns
     {
          get 
          {
               object out = null;
               if (As.Any()) out = As.Cast<object>().ToList(); 
               else if (Bs.Any()) out = Bs.Cast<object>().ToList(); 
               else if (Cs.Any()) out = Cs.Cast<object>().ToList();

               return out;
          }
     }   
 
}
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
14.06.2016, 06:47
    #39255418
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# фабрика классов EF Code First
Возобновлю тему, появился вопрос.
Использую данный пример в моем приложении.
Код: 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.
public abstract class Main
{
     [Key]
     public int Id { get; set; }
     public string  Name { get; set; } 

     public abstract ICollection<object> Foreigns { get; }
}

public class MainA : Main
{
     public virtual ICollection<A> As{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return As.Cast<object>().ToList(); }
     }
}

public class MainB : Main
{
     public virtual ICollection<B> Bs{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return Bs.Cast<object>().ToList(); }
     }
}

public class MainC : Main
{
     public virtual ICollection<С> Cs{ get; set; }

     public override ICollection<object> Foreigns 
    { 
         get { return Cs.Cast<object>().ToList(); }
     }
}



Подскажите пожалуйста, почему при запросе на прямую Main , у меня Foreigns пустой?
Код: c#
1.
var query = contextDb.Set<Main>().ToList();



Не пустой он только в том случае, если использовать метод Load()
Код: c#
1.
2.
3.
4.
contextDb.Set<A>().Load();
contextDb.Set<B>().Load();
contextDb.Set<C>().Load();
var query = contextDb.Set<Main>().ToList();



Почему так? Ведь там есть служебное поле Discriminator.
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / c# фабрика классов EF Code First / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]