RIA服务没有返回包含类型集合属性

3
我有一个WCF RIA Services应用程序和一个包含UserPermission对象集合的UserRole类型的模型。在域服务中,我使用.Include("UserPermission"),当我进行调试时,我已经验证它在返回之前绝对包含了UserPermission类型。
当我调试Silverlight 3客户端时,它返回了UserRoles,但UserPermission属性都是空的。这些UserRoles与服务上显示有UserPermissions相同。
由于服务和客户端上似乎一切正常,因此我专注于元数据类,但仍然找不到任何错误。
[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());
}

有人知道可能导致这些实体丢失的原因吗?我在其他几个地方也做了同样的事情,它们是正常工作的。
1个回答

7

好的,问题已解决!我使用Fiddler查看了服务器和客户端之间传递的序列化数据,并发现所有嵌套类型都被传递了,但它们之间的关系不正确。经过一些调试、思考和在线研究,发现EF中的多对多关系并不像预期那样工作,如果你依赖一个中间表来管理关系,则需要在模型中包含这些表。

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

1)进入数据库并更新中间表(管理多对多关系的表),添加一个主键标识列。一旦添加了这个列,EF生成的模型将包括这些表。

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

3)我必须添加所有新中间类型的元数据类,并更新现有类型的元数据类。我编写了一个VS代码片段(输入“meta”),以更快地添加这些类。您可以从这里下载安装程序。

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,但我希望它能改善所有这些问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接