Запрос Entity Framework для начинающих, чтобы заполнить WinForms ListView - PullRequest
1 голос
/ 04 апреля 2009

Я только начал изучать, как использовать Entity Framework для написания очень простой программы мониторинга сети на C # - это учебное упражнение, чтобы попытаться «добраться домой» до того, что я только что прочитал на сегодняшний день. Я также новичок в C # и LINQ (просто чтобы усложнить ситуацию.)

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

База данных содержит 3 таблицы:

[Server]    - A server defined by the user that should be pinged.
ServerID    - primary key
HostAddress - IP or hostname

[Result]    - A result containing data about the last server test
ResultID    - primary key
ServerID    - foreign key on [Server].[ServerID]
StateID     - an integer used to lookup one of 3 possible Server states
TimeStamp   - Time stamp of last ping

[State]     - A lookup table containing an integer -> string mapping.
StateID     - a unique key
StateLabel  - human-readable string like "unreachable" or "OK" or "timeout"

Я вручную заполнил базу данных, используя несколько простых записей - достаточно, чтобы мне было с чем работать.

Для начала я хотел бы представить все данные Result в ListView на WinForm. ListView содержит следующие статические столбцы:

Штат | Адрес сервера | Последняя проверка

Теоретически, данные ListView должны генерироваться путем проецирования (?) На каждую из 3 таблиц:

  • В столбце «Состояние» должен отображаться читабельный [State]. [StateLabel], связанный с [Result]. [StateID]
  • В столбце «Адрес сервера» должен отображаться [Server]. [HostAddress], связанный с [Result]. [ServerID]
  • В столбце «Последняя проверка» должен отображаться [Результат]. [TimeStamp]

Поскольку мне не нужны функции материализации объектов и / или отслеживания изменений ObjectServices, правильно ли я считаю, что было бы более эффективно / правильно использовать Entity SQL / EntityClient и DbDataReader? Если да, то как будет выглядеть подходящий запрос Entity SQL?

Для чего бы то ни было, я пытался использовать LINQ to Entities и анонимные типы в методе, но был расстроен отсутствием понимания подходящего возвращаемого типа:

var results = from r in _context.Result
select new
{
    State = (from s in _context.State
         where s.StateId == r.StateId
         select s.StateLabel),
    r.ServerReference.Value.HostAddress,
    r.TimeStamp
};

return results.ToList(); // <- No can do.

Спасибо за вашу помощь!

Steve

1 Ответ

1 голос
/ 04 апреля 2009

Ну, вы не сможете вернуть список анонимных типов, если вы не приведете их к object и не установите сигнатуру для типа возврата как List<object> (или подходящий интерфейс). Другая ваша проблема заключается в том, что подзапрос для State на самом деле будет возвращать IQueryable вместо одной записи (вы можете использовать метод расширения First с EF, чтобы получить первый соответствующий элемент). Модель также должна иметь свойство навигации для состояния, и вы должны иметь возможность использовать присоединенное свойство вместо подзапроса. Поэтому, если вы хотите использовать это как вызов метода, который возвращает список объектов, вам нужно будет создать тип, представляющий преобразование или преобразование объекта в объект. В противном случае вы можете сделать это на уровне формы (все зависит от ваших потребностей), где вы пытаетесь связать список.

public List<object> GetStuff()
{
    var results = from r in _context.Result
    select new
    {
        State = r.StateNavigationProperty.StateLabel, //If FK
        State = _context.State.First(state => state.StateId == r.StateId), //If Not FK
        HostAddress = r.ServerReference.Value.HostAddress,
        TimeStamp = r.TimeStamp
    };

    return results.Cast<object>().ToList();
}

...

myListView.DataSource = GetStuff();

И, как я уже сказал, другой альтернативой является либо создание класса для преобразования, либо привязка списка непосредственно к запросу.

public class SimpleStuff
{
    public string State { get; set; }
    public string HostAddress { get; set; }
    public DateTime TimeStamp { get; set; }
}

Затем просто добавьте класс в select new ala select new SimpleStuff и измените сигнатуру метода, чтобы отразить класс, и удалите приведение в возвращении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...