【问题标题】:A beginners Entity Framework query to populate a WinForms ListView用于填充 WinForms ListView 的初学者实体框架查询
【发布时间】:2009-04-04 06:09:39
【问题描述】:

我刚刚开始学习如何使用实体框架来编写一个非常简单的 C# 网络监控程序 - 这是一个学习练习,尝试“开车回家”我迄今为止只读过的内容。我也是 C# 和 LINQ 的新手(只是为了让事情进一步复杂化。)

我相信我已经对数据模型进行了适当的规范化,但我可能错了。 Visual Studio 生成一个看起来不错的概念模型。我已经在必要时对关联和实体集进行了复数化,但我正在努力执行我认为是相当基本的数据查询/投影。

数据库包含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"

我已经使用一些简单的条目手动填充了数据库 - 足以给我一些可以使用的东西。

对于初学者,我想在 WinForm 上的 ListView 中显示所有结果数据。 ListView 包含以下静态列:

状态 |服务器地址 |上次检查

理论上,ListView 的数据需要通过对 3 个表中的每一个进行投影(?)来生成:

  • “状态”列应显示从 [Result].[StateID] 链接的人类可读的 [State].[StateLabel]
  • “服务器地址”列应显示 [Server].[HostAddress] 链接自 [Result].[ServerID]
  • “上次检查”列应显示 [Result].[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.

感谢您的帮助!

史蒂夫

【问题讨论】:

    标签: c# winforms entity-framework listview


    【解决方案1】:

    好吧,除非您将匿名类型转换为object 并让签名将返回类型定义为List&lt;object&gt;(或合适的接口),否则您将无法返回匿名类型列表。您的另一个问题是 State 的子查询实际上将返回一个 IQueryable 而不是单个条目(您可以使用带有 EF 的 First 扩展方法来获取第一个匹配项。)尽管如果您有外键关系模型还应该为状态设置导航属性,并且您应该能够使用附加的属性而不是子查询。因此,如果您希望将此作为返回对象列表的方法调用,则必须创建一个表示转换或向下转换为对象的类型。否则,您可以在尝试绑定列表的表单级别(这完全取决于您的需要)执行此操作。

    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 并更改方法签名以反映类并删除返回中的强制转换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 2015-09-28
      • 2019-11-02
      • 2013-09-02
      相关资源
      最近更新 更多