none
Расширить сущность EDM своим полем RRS feed

  • Вопрос

  • Добрый день!

    Как мне расширить сущность EDM своим полем, например:

    У меня в базе есть сущность product

    product_id int

    productName varchar(32)

    container_id int -- это FK из таблицы контейнер

     

    таблица container:

    container_id int

    containerName varchar(32)

     

    Так вот я генерирую EDM, которая соответственно создает 2 сущности EDM product и container и свзяывает их,

    так вот, как мне добавить в первую(product) сущность поле containerName, которая бы отображала поле containerName из сущности container по

    значению поля container_id из product?

    Заранее спасибо за ответ.

     

    17 ноября 2011 г. 11:25

Ответы

  • Изначальный вопрос:

    "Так вот я генерирую EDM, которая соответственно создает 2 сущности EDM product и container и свзяывает их,

    так вот, как мне добавить в первую(product) сущность поле containerName, которая бы отображала поле containerName из сущности container по

    значению поля container_id из product?"

    У вас класс Product имеет член Container?

    Напишите

    public partial class Product
    {
    public string ContainerName {get {return Container.Name;}}
    }


    При обращении к этому свойству из загруженного в память объекта Product, оно подгрузится из базы. Это и есть LazyLoading.

    В вашем же случае при обращении к этому свойству будет каждый раз создаваться контекст данных чтобы загрузить это свойство каким-то хитрым джойном. Представьте, что вам надо считать значение ContainerName у 100 продуктов, и посчитайте, сколько раз при этой простой операции будет выполняться "using (ManufactureEntities mEntity = new ManufactureEntities())...."

    Как перетащить это на форму, это другой вопрос. Мышкой справиться не получится, а вот отредактировать отображение, определив соотв. столбец можно. 

    Если с этим сложности, повторяю, постройте нужную вьюху в базе, отразите  на EDM модель и перетащите на форму.

    • Помечено в качестве ответа svfaust 18 ноября 2011 г. 10:49
    18 ноября 2011 г. 10:28
  • Все правильно говорите, спасибо.

    Я разобрался, вот как раз через пост выше, просто не сразу сообразил).

    Да как добавить я сообразил, добавил поле и проставил field ContainerName.

    • Помечено в качестве ответа svfaust 18 ноября 2011 г. 10:49
    18 ноября 2011 г. 10:35

Все ответы

  • Можно так:

     

    namespace SomeYourModel {

     

    public partial class product {

        public string containerName {get { return "tralala"; } }

    }

    }

    • Предложено в качестве ответа Abolmasov Dmitry 17 ноября 2011 г. 13:59
    17 ноября 2011 г. 13:38
  • Используйте частичные классы, как и предложил Nick.

    Не забудьте отменить ответ. Спасибо.


    Для связи [mail]
    17 ноября 2011 г. 13:58
  • Я пробовал:

    namespace Manufacture.DB
    {
    
      public partial class product : EntityObject
      {
        /// <summary>
            /// Нет доступной документации по метаданным.
            /// </summary>
            ///
        
        
            [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
            [DataMemberAttribute()]
            public global::System.String СName
            {
                get
                {
                    return _productName;
                }
            }
    
       
      }   
    }

    Но это свойство не отражается, в EDM модели и соответственно в списке объектов, когда кидаешь этот объект в привязке GridView

     


    • Изменено svfaust 17 ноября 2011 г. 14:05
    17 ноября 2011 г. 14:03
  • Действительно помогло, отображает, но приходится прописывать руками это свойство в GridView, автоматически не генерируется.

    Но тут же возник другой вопрос.

    public partial class product : EntityObject
      {
        /// <summary>
            /// Нет доступной документации по метаданным.
            /// </summary>
            ///
        
            public global::System.String СName
            {
                get
                {
                  int? container_id = this.container_id;
    
    
                  var query = (from cont in container
                               join measure in this.container.refMeasure on cont.measure_id equals measure.measure_id
                               where cont.container_id == container_id
                               select new { contName = cont.containerName, contCapacity = cont.containerCapacity, measName = measure.measureName }).First();
    
    
                  //e.DisplayText = drv["CategoryName"] + " " + drv["container_id"];
    
    
                  return query.contName + " " + System.Convert.ToString(query.contCapacity) + " " + query.measName;
                }
            }
    
       
      }
    


    Но ругается, что:

    Ошибка 5 Не удается найти реализацию шаблона запроса для типа источника "Manufacture.DB.container". "Join" не найден. D:\work\OutSource\manufacture\application\Manufacture\DB\extention.cs 25 41 Manufacture

    Так как же мне достучатся до подчиненой таблице, в которой и есть это Name?

    Еще раз спасибо.

    17 ноября 2011 г. 14:22
  • Все спасибо, разобрался, я делаю это вот так, правда вот отображения этого свойства в модели нет.

     

    public partial class product : EntityObject
      {
        /// <summary>
            /// Нет доступной документации по метаданным.
            /// </summary>
            ///
        
            public global::System.String СName
            {
                get
                {
                  int? container_id = this.container_id;
    
                  /*
                  var query = (from cont in this.container join measure in this.container.refMeasure on cont.measure_id equals measure.measure_id
                               where cont.container_id == container_id
                               select new { contName = cont.containerName, contCapacity = cont.containerCapacity, measName = measure.measureName }).First();
    
                  */
    
                  //container cnt = (this.container as Manufacture.DB.container);
                  using (ManufactureEntities mEntity = new ManufactureEntities())
                  {
    
                    var query = (from cont in mEntity.container
                                 join measure in mEntity.refMeasure on cont.measure_id equals measure.measure_id
                                 where cont.container_id == container_id
                                 select new { contName = cont.containerName, contCapacity = cont.containerCapacity, measName = measure.measureName }).First();
    
    
                    //return query.contName + " " + System.Convert.ToString(query.contCapacity) + " " + query.measName;
                    return query.contName + " " + System.Convert.ToString(query.contCapacity) + " " + query.measName;
                  }
                }
            }
    
       
      }
    

    17 ноября 2011 г. 14:57
  • Ваше решение с определением getter'a архитектурно ужасно )

    Представьте, что классы сущностей расширятся, и потребуются другие объединения. В каждом getter-е свойства будет создаваться экземпляр ManufactureEntities()?

    Если вы сгенерировали EDM модель по базе, где есть связь между таблицами с использованием внешнего ключа,

    то Product уже будет иметь навигационное свойство Container.

    Можно использовать проекцию для извлечения связанных данных:

     

    _dbContext.Products
    .Select(s => new {s, s.Container.Name}).First(x => x.Id == someId);

    Можно использовать Lazy Loading, просто обращаясь к нав. свойству:

    var name = product.Container.Name;

    Если надо просто перетащить сгенерированные сущности на форму, а проекцию и Lazy Loading использовать нельзя, то создайте в самой базе данных View что-нибудь типа "FullProductJoin", в которой объедините необходимые данные из нескольких таблиц. Уже эту вьюху можно отразить на EDM модель и перетащить на форму.

     


    • Изменено J.W.Harding 18 ноября 2011 г. 5:14
    18 ноября 2011 г. 5:14
  • Не совсем понял, а где прописывать вот такую строку:

    dbContext.Products.Select(s => new {s, s.Container.Name}).First(x => x.Id == someId);
    

     

     

    В моем случае, я делаю расширение класса, которое я всегда могу исправить, вне зависимости от перегенерации модели.

    Если вот эту строку, я могу прописать в расширенни класса:

     

    public partial class product : EntityObject
    

    То я не понимаю откуда мне брать контекст(dbContext)?

     

    Похоже я понял, у меня же экземляр класса и значение в нем единственное, поэтому можно сделать вот так:

     

    public partial class product : EntityObject
      {
        /// <summary>
            /// Нет доступной документации по метаданным.
            /// </summary>
            ///
            [DataMemberAttribute()]
            public global::System.String СName
            {
                get
                {
    
                  #region <for memory>
                  /*
                  using (ManufactureEntities mEntity = new ManufactureEntities())
                  {
    
                    var query = (from cont in mEntity.container
                                 join measure in mEntity.refMeasure on cont.measure_id equals measure.measure_id
                                 where cont.container_id == container_id
                                 select new { contName = cont.containerName, contCapacity = cont.containerCapacity, measName = measure.measureName }).First();
    
    
                    return query.contName + " " + System.Convert.ToString(query.contCapacity) + " " + query.measName;
                  }
                   */
                  #endregion 
    
                  return this.container.containerName + " " + System.Convert.ToString(this.container.containerCapacity) + " " + this.container.refMeasure.measureName;
                  
                }
            }
    
      } 

     



    • Изменено svfaust 18 ноября 2011 г. 8:46
    18 ноября 2011 г. 8:39
  • Изначальный вопрос:

    "Так вот я генерирую EDM, которая соответственно создает 2 сущности EDM product и container и свзяывает их,

    так вот, как мне добавить в первую(product) сущность поле containerName, которая бы отображала поле containerName из сущности container по

    значению поля container_id из product?"

    У вас класс Product имеет член Container?

    Напишите

    public partial class Product
    {
    public string ContainerName {get {return Container.Name;}}
    }


    При обращении к этому свойству из загруженного в память объекта Product, оно подгрузится из базы. Это и есть LazyLoading.

    В вашем же случае при обращении к этому свойству будет каждый раз создаваться контекст данных чтобы загрузить это свойство каким-то хитрым джойном. Представьте, что вам надо считать значение ContainerName у 100 продуктов, и посчитайте, сколько раз при этой простой операции будет выполняться "using (ManufactureEntities mEntity = new ManufactureEntities())...."

    Как перетащить это на форму, это другой вопрос. Мышкой справиться не получится, а вот отредактировать отображение, определив соотв. столбец можно. 

    Если с этим сложности, повторяю, постройте нужную вьюху в базе, отразите  на EDM модель и перетащите на форму.

    • Помечено в качестве ответа svfaust 18 ноября 2011 г. 10:49
    18 ноября 2011 г. 10:28
  • Все правильно говорите, спасибо.

    Я разобрался, вот как раз через пост выше, просто не сразу сообразил).

    Да как добавить я сообразил, добавил поле и проставил field ContainerName.

    • Помечено в качестве ответа svfaust 18 ноября 2011 г. 10:49
    18 ноября 2011 г. 10:35