【问题标题】:RIA Services not returning Included Type Collection PropertyRIA 服务未返回包含类型集合属性
【发布时间】:2011-02-07 03:16:23
【问题描述】:

我有一个 WCF RIA 服务应用程序和一个包含 UserPermission 对象集合的 UserRole 类型的模型。我在域服务中使用 .Include("UserPermission") ,当我调试它时,我已经验证它在返回之前肯定包含 UserPermission 类型。

当我调试 Silverlight 3 客户端时,它返回 UserRoles,但 UserPermission 属性全部为空。这些是在服务上显示具有 UserPermissions 的相同 UserRoles。

由于服务和客户端上的一切看起来都是正确的,我专注于元数据类,但仍然找不到任何错误。

[MetadataTypeAttribute(typeof(UserRole.UserRoleMetadata))]
public partial class UserRole
{
    internal sealed class UserRoleMetadata
    {
        public int RoleID;
        public string Name;

        [Include]
        [Association("UserPermissions", "RoleID", "PermissionID")]
        public EntityCollection<UserPermission> UserPermissions;
    }
}

域服务方法如下:

public IEnumerable<UserRole> GetUserRoles()
{
    IEnumerable<UserRole> roles = this.ObjectContext.UserRole.Include("UserPermissions");
    return roles; // In debug, roles.First().UserPermissions.Count = 2 here
                  // For now, there is only one single role in the ObjectContext and it has
                  // two UserPermissions
}

这是 Silverlight 客户端方法:

context.Load(context.GetUserRolesQuery(), loadOp =>
{
    IEnumerable<UserRole> roles = loadOp.Entities;
    // This should show 2, but shows 0:
    MessageBox.Show("Permissions loaded: " + roles.First().UserPermissions.Count.ToString());
}

有谁知道可能导致这些包含的实体丢失的任何事情?我在其他几个地方也做过同样的事情,它们也能正常工作。

【问题讨论】:

    标签: c# entity-framework .net-3.5 wcf-ria-services


    【解决方案1】:

    好的,解决了!我查看了使用Fiddler 在服务器和客户端之间传递的序列化数据,发现实际上所有嵌套类型都在传递,但它们之间的关系不正确。经过一些修补、思考和在线研究,结果发现 EF 中的多对多关系无法按预期工作,如果您依靠中间表来管理您的关系需要在模型中包含这些表。

    为了让我的应用程序正常工作,我执行了以下操作:

    1) 进入数据库并通过添加主键标识列更新中间表(管理多对多关系的表)。添加后,EF 生成的模型将在更新时包含这些表。

    2) 为了彻底清除我现有的模型,我使用了重命名数据库中的表、更新模型、重命名数据库表,然后再次更新并选择我想要添加的表的技巧。这可能有点矫枉过正,但由于我过去遇到的问题,我发现这是确保桌子完全干净的最佳方法。

    3) 我必须为新的中间类型添加所有元数据类,并为现有类型更新元数据类。我写了一个 VS sn-p (type 'meta') 来更快地添加这些类。您可以下载安装程序here

    4) 除了添加/更新所有现有的元数据类之外,您还需要确保所有“AssociationAttributes”都使用中间类型并指定外键属性:

    [MetadataTypeAttribute(typeof(UserPermissionMembers.UserPermissionMembersMetadata))]
    public partial class UserPermissionMembers
    {
        internal sealed class UserPermissionMembersMetadata
        {
            private UserPermissionMembersMetadata()
            {}
    
            public int ID;
            public UserRole UserRole;
    
            [Include]
            [Association("UserPermission", "fkPermissionID", "PermissionID", IsForeignKey = true)]
            public UserPermission UserPermission;
        }
    }
    

    5) 我用新结构更新了域服务方法:

    public IEnumerable<UserRole> GetUserRoles()
    {
        IEnumerable<UserRole> roles = this.ObjectContext.UserRole.Include("UserPermissionMembers.UserPermission");
        return roles;
    }
    

    6) 我更新了客户端方法以利用新类型。

    context.Load(context.GetUserRolesQuery(), loadOp =>
    {
        IEnumerable<UserRole> roles = loadOp.Entities;
        MessageBox.Show("Permissions loaded: " + roles.First().UserPermissionMembers.Count.ToString());
    }
    

    注意:即使知道问题,仍然需要一段时间才能正确配置所有 AssociationAttributes,以便它们引用正确的属性。如果您遇到问题,我建议您仔细检查那里。

    对于应该更优雅的东西来说,这是一个很大的痛苦。我还没有看过 EF v4,但我希望它能改进这一切。

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多