LINQ to Entities - Лучший способ сделать это? - PullRequest
2 голосов
/ 01 января 2011

ОК, я в основном разработчик LAMP, поэтому я новичок в этой структуре. Тем не менее, я знаком с основами в LINQ и сгенерировал модель сущности из моей БД. Теперь вот мое требование:

У меня есть сетка данных в WinForm, которая будет обновляться из источника данных на удаленном сервере каждые несколько секунд, поскольку изменения в наборе данных производятся из других источников. Очевидно, я хотел бы создать лямбда-выражение, чтобы получить правильный анонимный тип, чтобы удовлетворить столбцы, которые должны быть показаны в моей таблице данных. Я сделал это, и вот результат (я использую пользовательский элемент управления сеткой данных, кстати):

alt text

И мой код пока:

Models.dataEntities objDB = new Models.dataEntities();

var vans = from v in objDB.vans
           select v;

gcVans.DataSource = vans;

ОК, теперь у меня есть базовый набор данных. Одна из проблем, с которыми я столкнулся, заключается в том, что в столбце «Состояние» будет показана рассчитанная строка, основанная на нескольких параметрах в наборе данных. Я добавил это к своим сущностям через частичный класс. Как вы можете видеть на скриншоте, это работает правильно:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1.Models {

    public partial class van {

        public string van_status {

            get {

                if (this.is_offline == 1) {

                    return "Offline";

                } else if (this.is_prayer_room == 1) {

                    return "In Prayer Room";

                } else {

                    return "TODO: Create statuses";

                }

            }

        }

    }

}

Это добавленное свойство отлично работает. Однако, во второй раз, когда я пытаюсь проецировать статус в анонимном типе, чтобы я мог также получить название школы, я получаю сообщение об ошибке:

Models.dataEntities objDB = new Models.dataEntities();

var vans = from v in objDB.vans
           select new {

               van_name = v.van_name,
               school_name = v.school.school_name,
               capacity = v.capacity,
               phone = v.phone,
               van_status = v.van_status

           };

gcVans.DataSource = vans;

alt text

Итак, у меня два вопроса:

1) Если я не могу использовать вычисленные свойства моих частичных классов в проекциях LINQ, как я могу показать свою вычисленную строку в моей сетке данных?

2) Я даже правильно подхожу к этому? Когда я решу # 1, как мне обновить эти данные (то есть во время события срабатывания таймера)? Могу ли я просто позвонить objDB.refresh(), а затем сказать, чтобы моя сетка данных обновлялась из источника данных? Запускает ли этот метод на самом деле лямбда-выражение, описанное выше, или он загружает все из БД?

Спасибо за любую помощь с этим. Кроме того, если у вас есть какие-либо лучшие практики, чтобы поделиться, это было бы здорово! Надеюсь, я объяснил это так подробно, как вам нужно, чтобы оказать помощь.

Ответы [ 2 ]

3 голосов
/ 01 января 2011

1) Вместо того, чтобы модифицировать свой объект EF частичным классом, вы всегда можете создать свой собственный класс, содержащий ваше свойство только для чтения van_status. Код, который вы получили, был бы почти идентичен:

Models.dataEntities objDB = new Models.dataEntities();
gcVans.DataSource = from v in objDB.vans
           select new DisplayVan {
               van_name = v.van_name,
               school_name = v.school.school_name,
               capacity = v.capacity,
               phone = v.phone,
           };

Свойство van_status, поскольку оно доступно только для чтения, не нужно указывать в запросе.

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

Я не хочу доверять методам .Refresh () и надеюсь, что все работает с максимальной эффективностью и работает должным образом. Вместо этого, инкапсулируйте код из # 1 в свой собственный метод и вызовите его при срабатывании события таймера (или как вы решите реализовать периодическое обновление).

1 голос
/ 01 января 2011

Еще одним хорошим вариантом будет создание метода расширения.

Вот простой пример:

using System;

namespace WindowsFormsApplication1 {
    static class Program {
        [STAThread]
        static void Main() {
            Van van = new Van();
            string status = van.GetStatus();
        }
    }

    public static class VanExtension {
        public static string GetStatus(this Van van) {
            if(van.is_offline == 1) {
                return "Offline";
            }
            else if(van.is_prayer_room == 1) {
                return "In Prayer Room";
            }

            return "TODO:  Create statuses";
        }
    }

    public class Van {
        public int is_offline { get; set; }
        public int is_prayer_room { get; set; }
    }
}
  • Обязательно поместите этот класс расширения в то же пространство имен, что и класс сущности.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...