RIA服务不返回包含的类型集合属性属性、类型、RIA

2023-09-07 10:00:33 作者:、自作贱,不可悔

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

I have a WCF RIA Services app and a model with a UserRole type that contains a collection of UserPermission objects. I use .Include("UserPermission") in the domain service and when I debug it I've verified it definitely contains the UserPermission types before returning.

当我调试Silverlight 3的客户端返回的UserRoles但UserPermission属性都是空的。这些是显示对服务具有UserPermissions相同UserRoles

When I debug the Silverlight 3 client it returns the UserRoles but the UserPermission properties are all empty. These are the same UserRoles that show having UserPermissions on the service.

既然一切出现在服务和客户端正确的,我集中在元数据类,但仍然无法发现任何错误。

Since everything appears correct on the service and client, I'm focussing on the metadata class, but still can't find anything wrong.

[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;
    }
}

下面是该领域的服务方式:

Here's the domain service method:

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客户端方式:

Here's the Silverlight client method:

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());
}

有谁知道任何可能导致这些包括实体的损失?我这样做同样的事情在其他几个地方和他们的工作。

Does anyone know of anything that might cause a loss of these included entities? I do this same thing in several other places and they work.

推荐答案

确定,解决它!我看了看序列化的数据被使用提琴手中的服务器和客户机之间传递,发现所有的嵌套类型实际上是被传递,但它们之间的关系是不正确的。经过一番摆弄,思考,在线研究,原来的多到许多在EF的关系并不如预期工作,如果你依赖于中介表来管理的关系,你需要包括在模型中的那些表。

OK, solved it! I took a look at the serialized data being passed between the server and client using Fiddler and found that all the nested types were in fact being passed but the relationships between them weren't correct. After some tinkering, thinking, and online research, it turned out many-to-many relationships in the EF don't work as expected and if you're relying on an intermediary table to manage the relationships you need to include those tables in the model.

要获得我的应用程序工作,我做了以下内容:

To get my app to work I did the following:

1)刚一进DB和更新中间表(用于管理多对多的关系)加入主键标识列的那些。一旦被添加时更新EF-生成的模型将包含这些表。

1) Went into the DB and updated the intermediary tables (the ones that manage the many-to-many relationships) by adding a primary key identity column. Once this is added the EF-generated model will include these tables when updated.

2)要消灭我现有的模型完全,我用重命名我的表在数据库中,更新模型,重命名数据库表背,然后再次更新,并选择我想添加的表的伎俩。这可能是矫枉过正,但由于问题我已经在过去,我发现它,以确保表是完全干净的最好方法。

2) To wipe out my existing model completely, I used the trick of renaming my tables in the DB, updating the model, renaming the DB tables back, and then updating again and selecting the tables I want added. This might be overkill but due to issues I've had in the past I find it's the best way to ensure the tables are completely clean.

3)我不得不添加的所有元数据类新的中间类型以及更新元数据类的现有类型。我添加这些类快一点写了一个VS片段(型元)。你可以在这里下载安装。

3) I had to add all the metadata classes for the new intermediate types as well as update the metadata classes for the existing types. I wrote a VS snippet (type 'meta') for adding these classes a little quicker. You can download the installer here.

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

4) In addition to adding/updating all the existing metadata classes, you need to ensure all your 'AssociationAttributes' use the intermediary types and specify the foreign key properties:

[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)我更新了域名服务方法与新的结构:

5) I updated the domain service method with the new structure:

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

6)我更新的客户机的方法,以利用新的类型。

6) I updated the client method to utilize the new types.

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

请注意:即使知道问题仍需要一段时间来正确地配置所有的AssociationAttributes,使它们指向正确的属性。如果您有任何问题,我建议你仔细检查那里。

NOTE: Even knowing the problem it still took a while to properly configure all the AssociationAttributes so that they refer to the correct properties. If you're having issues, I suggest you double-check there.

这是很多痛苦的东西,应该是更优雅。我没有看过EF V4,但是我希望它改善了这一切。

This is a lot of pain for something that should be more elegant. I haven't looked at EF v4 yet but I hope it improves all this.

 
精彩推荐