【问题标题】:MVVM light datagrid loading from two relational database tables从两个关系数据库表加载 MVVM 轻型数据网格
【发布时间】:2010-07-19 12:55:48
【问题描述】:

如何使用 MVVM light 加载包含两个相关表的 DataGrid,我使用的是 .NET RIA 和 silverlight 4。

例如,如果我的数据表是:

用户信息- 用户 ID、姓名、地址 ID
地址 - 地址 ID、街道名称、邮编

如何创建显示 [Name, StreetName, ZIp] 的数据网格

【问题讨论】:

    标签: silverlight mvvm datagrid light


    【解决方案1】:

    首先,您必须在您的 DomainService 类中的 UserInfo 的 GetQuery 中包含地址表,如下所示...

      [Query]
      public IQueryable<UserInfo> GetUserInfos()
        {
            return this.ObjectContext.UserInfos.Include("Address");
        }
    

    然后在元数据文件中,您必须在

    上方添加 [Include]
      [Include]
            public Addresses Address{ get; set; }
            public int AddressID { get; set; }
    

    现在构建解决方案。 现在在 Xaml 中你可以像这样使用

      <sdk:DataGrid ItemsSource="{Binding UserList, Mode=TwoWay}" SelectedItem="{Binding CurrentUser, Mode=TwoWay}" Margin="0,0,0,2" AutoGenerateColumns="False">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
                <sdk:DataGridTextColumn Header="Street Name" Binding="{Binding Path=Address.StreetName}"/>
                <sdk:DataGridTextColumn Header="Zip" Binding="{Binding Path=Address.Zip}"/>
            </sdk:DataGrid.Columns>
    
        </sdk:DataGrid>
    

    【讨论】:

      【解决方案2】:

      这里有几种可能的方法。我会解释这两个想到的。首先,使用数据库中已经定义的关系。二是通过自定义模型类返回。

      选项 1: 我将假设您已经从 Web 项目的数据库中创建了一个实体框架模型(具有关系),并创建了 DomainService 来托管该模型。 !!!创建模型时要做的一个关键是为模型创建元数据类!!! (前几次我错过了这一点,修改模型的行为至关重要,例如您在此处需要的)

      在元数据模型中,您会找到关联属性,并使用 [Include] 属性对其进行装饰。这是我从另一个带有 WorklanDetail 的项目中获得的示例,我想在其中返回关联的分配:

      [MetadataTypeAttribute(typeof(WorkplanDetailMetadata))]
      public partial class WorkplanDetail
      {
          internal sealed class WorkplanDetailMetadata
          {
              [Include]
              public EntityCollection<Assignment> Assignments { get; set; }
          }
      }
      

      然后,您只需在 Silverlight 应用程序中引用该属性,就可以使用您的地址数据。

      要绑定单个实体(实体引用,而不是集合),那么您只需使用您的属性来访问数据网格绑定上的子实体...例如:

      Text="{Binding Path=Address.StreetName}"
      

      这是我所知道的最简单的方法。

      选项 2 需要创建您自己的自定义类(您必须至少有一个用 [Key] 属性装饰的属性,以方便与客户端之间的传输)。下面是一个例子,我曾经用来获取文件夹搜索结果信息:

      public class FolderSearchResult
      {
          [Key]
          public string EFOLDERID { get; set; }
          public string Subject { get; set; }
          public string FolderName { get; set; }
      }
      

      关键在于 EFOLDERID 属性具有 [Key] 属性,该属性唯一标识每个项目,就像数据库中的 PK 一样。

      然后在你的服务类中你可以这样返回:

      public IEnumerable<FolderSearchResult> GetFolderResults(string search)
          {
              var query = from ge in this.ObjectContext.Generic_Engagement
                          from f in this.ObjectContext.eFolders
                          where ge.EFOLDERID == f.eFolderID &
                          f.eArchived == 0 &
                          f.eSubject.Contains(search) &
      
                          (from wp in this.ObjectContext.Workplans
                           where wp.EFOLDERID == f.eFolderID
                           select wp).Count() == 0 &
      
                           (from r in this.ObjectContext.Resources
                            where r.EFOLDERID == f.eFolderID
                            select r).Count() == 0
      
                          select new FolderSearchResult()
                            {
                              EFOLDERID = f.eFolderID,
                              FolderName = f.eFolderName,
                              Subject = f.eSubject
                            };
              return query.AsEnumerable<FolderSearchResult>();
          }
      

      关于这种方法的几点说明:

      1. 在我看来,这在您不需要只读访问权限时效果最佳。如果您要进行更新/插入/删除,请使用第一种方法。
      2. 当您需要在完全不同的数据源(可能是数据库中的用户 ID 和员工 ID,以及 Active Directory 中的显示名称、站点位置等)之间创建一些逻辑对象时,这非常有用。
      3. 以这种方式更新是可能的,但您必须做更多的工作来分离您的项目并正确更新所有内容。

      总的来说,我建议使用第一种方法,除非发生以下情况:您需要一个跨越数据存储的逻辑对象(单独的数据库源),或者您需要快速只读访问(例如 ItemSource 绑定用于 drop -下列表)。

      将排序和过滤逻辑卸载到服务器,即使以在内存中加载额外的实体为代价,以便您的客户端可以保持快速,根据我的经验,这是有好处的。在 CollectionViewSource 中使用本地排序或其他方式也可以做到这一点,但其中的一些可能会真正开始减慢您的应用程序速度。

      【讨论】:

        猜你喜欢
        • 2014-08-30
        • 2019-07-29
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多