Динамическое переключение между ADO.NET модели сущностей

#c# #asp.net #ado.net

#c# #asp.net #ado.net

Вопрос:

Это .net 4 в версии vs 2010. У меня есть несколько баз данных с одинаковой структурой. В конечном итоге мы объединим их в одну, но это далеко не так. Я пишу приложение и, чтобы избежать необходимости писать один и тот же код 10 раз, я хочу динамически переключаться между моделями. Я близок, но не совсем там. Вот что у меня есть:

 using esOrderHeader = Shipping.Models.esShip.OrderHeader;

using fnOrderHeader = Shipping.Models.fnShip.OrderHeader; //OrderHeader is a table in the database

    ObjectContext context = null;

    IEnumerable< EntityObject> orderHeader = null; //i've tried ObjectSet as well

    switch (client)
    {

         case "es":
                  context = new esshipEntities();
                  orderHeader = context.CreateObjectSet<esOrderHeader>();
                  break;

         case "fn":
                  context = new fnshipEntities();
                  orderHeader = context.CreateObjectSet<fnOrderHeader>();
                  break;

    }

var query = from row in orderHeader where row.IsFulfilled == false select row;
  

Следующее не будет компилироваться, потому что компилятор говорит «Не удается разрешить символ IsFulfilled», который является полем в моей таблице. Как я могу переключаться между сущностями и иметь возможность запускать запросы linq к ним?

Комментарии:

1. Он не может разрешить строку. Выполняется, поскольку OrderHeader имеет тип IEnumerable<EntityObject> . Я не уверен, что это сработает, но не могли бы вы попробовать создать суперкласс для вашей доставки. Модели. Сущее. OrderHeader (а также fnShip) и поместить туда свойство IsFulfilled, а затем использовать этот суперкласс вместо EntityObject? Я тоже попробую это сделать, дам вам знать, если это сработает для меня…

2. Кстати, вместо ‘строка. IsFulfilled == false’ вы могли бы просто вставить’!строка. Выполнено’ 🙂

3. Что ж, моя программа успешно скомпилирована (хотя не могу протестировать без создания базы данных). Вам повезло?

4. Пожалуйста, попробуйте, и если это сработает, опубликуйте свой пример. Я не уверен, как сделать то, что вы предлагаете.

5. Выполняйте обе функции. OrderHeader и esShip. У OrderHeader одинаковые свойства?

Ответ №1:

Что поможет вам скомпилировать ваш код (хотя я не уверен, что это хорошее решение :)), так это создание суперкласса для руководителей заказов для разных кораблей.

 namespace Shipping.Models
{
    class CommonOrderHeader
    {
        public bool IsFulfilled { get; set; }
    }
}

namespace Shipping.Models.fnShip
{
    class OrderHeader : CommonOrderHeader
    {

    }
}

namespace Shipping.Models.esShip
{
    class OrderHeader : CommonOrderHeader
    {

    }
}
  

Таким образом, вместо IEnumerable<EntityObject> orderHeader = null; того, чтобы использовать IEnumerable<CommonOrderHeader> orderHeader = null;

Поскольку EntityObject не содержит свойства IsFulfilled , ваш код не компилируется. CommonOrderHeader содержит это поле, и поэтому ваш код компилируется.

Надеюсь, у вас это получится 🙂

Комментарии:

1. Спасибо за публикацию, и я надеюсь, что это тоже сработает. Я не понимаю, как я могу заставить это работать таким образом, потому что классы модели сущностей были автоматически созданы Visual Studio, и это не было бы проблемой, если бы дизайнер поместил таблицы для моделей в тот же класс, что и модель, а не в отдельные классы. Я надеюсь, что это имеет смысл

2. Да, я знаю, что вы говорите, это может создать проблему, однако у меня есть другое решение: если вы не можете использовать суперкласс из-за их создания, вы можете использовать класс, который имеет интересующие свойства (т. Е. Те, Которые вы пытаетесь выбрать), изатем поместите свой запрос внутрь коммутатора и заставьте его возвращать объекты этого типа. Будет ли это приемлемым решением?

3. Если я понимаю, что вы говорите, разве это не то, чего я пытаюсь избежать, означая повторяющийся код?

4. К сожалению, да. 🙂 Просто я не вижу другого способа, которым вы могли бы даже использовать эти выбранные вами данные, если только они не одного типа (например, IEnumerable<SomeNewClass> или супертип). Кстати, как вы планировали извлекать данные из EntityObject?

5. Классы, от которых наследуются все таблицы, — это EntityObject , поэтому я предположил, что смогу.

Ответ №2:

Код выглядит нормально для меня… Можете ли вы проверить, правильно ли сопоставляется свойство «IsFulfilled» объекта с таблицей базы данных? «Orderheader» на самом деле должен быть Ienumerable .. это то, против чего вы пишете свой запрос linq .. верно? Единственное, о чем я мог подумать, это правильно ли отображается объект? Кроме того, существуют ли сущности и сущности в двух отдельных файлах edmx??

Комментарии:

1. да, esshipentities и fnshipentities — это два отдельных файла edmx. IsFulfilled отображается правильно, потому что я выполнял запросы к таблице OrderHeader, когда создавал экземпляр своего объекта следующим образом:

2. var OrderHeader = контекст. CreateObjectSet<esOrderHeader>();