公开 Ria 服务 SP1 和 EF 4.1 POCO 中的关联实体
我们最近将使用 RIA 服务和带有 EDMX 的 EF 4.0 的 Silverlight 4 应用程序升级到使用 POCO 的 RIA 服务 SP1 和 EF 4.1。这次升级非常值得,但 RIA 现在在客户端上公开关联实体的方式似乎有所不同。
例如,假设我们有以下 EF POCO,它们也是我们的 RIA 实体:
public class Building
{
public Building()
{
Rooms = new List<Room>();
}
[Key]
public int? BuildingID { get; set; }
public string Name {get; set;}
[Association("Building_1-*_Rooms", "BuildingID", "BuildingID")]
[Include]
[Composition]
public ICollection<Room> Rooms {get; set;}
}
public class Room
{
[Key]
public int? RoomID { get; set; }
[Required]
public int? BuildingID { get; set; }
public string Name {get; set;}
[Association("Building_1-*_Rooms", "BuildingID", "BuildingID", IsForeignKey= true)]
[Include]
public Building Building {get; set;}
[Association("Room_1-*_Desks", "RoomID", "RoomID")]
[Include]
[Composition]
public ICollection<Desk> Desks { get; set; }
}
public class Desk
{
[Key]
public int? DeskID { get; set; }
[Required]
public int? RoomID { get; set; }
public string Name { get; set; }
[Association("Room_1-*_Desks", "RoomID", "RoomID", IsForeignKey = true)]
[Include]
public Room Room { get; set; }
}
Building 是 Room 的父级,Room 是 Desk 的父级。 Association
属性定义 RIA 的这些关系。然后,我们使用一个简单的服务公开这些实体,该服务对所有三个实体都具有 CRUD
public class BuildingDomainService
{
var _context= new BuildingEFContext(); //Lets just say this is our EF Context that has all three types on it
public IQueryable<Buildings> GetBuildings()
{
return _context.Buildings.Include(x => x.Rooms.Select(y => y.Desks));
}
public IQueryable<Rooms> GetRooms()
{
return _context.Rooms.Include(x => x.Desks);
}
public IQueryable<Desk> GetDesks()
{
return _context.Desks;
}
//Empty Update and Insert Methods to allow editing on client
public void UpdateBuilding(Building building){}
public void InsertBuilding(Building building){}
public void DeleteBuilding(Building building){}
public void UpdateRoom(Room room){}
public void InsertRoom(Room room){}
public void DeleteRoom(Room room){}
public void UpdateDesk(Desk desk){}
public void InsertDesk (Desk desk){}
public void DeleteDesk (Desk desk){}
}
在客户端上,从 BuildingDomainService 生成的 BuildingDomainContext 具有三个公开方法(GetBuildingsQuery()、GetRoomsQuery() 和 GetDesksQuery()),但只有一个Building 类型的单个 EntitySet,该服务不会公开 Room 或 Desk 的 EntitySet。
在我们的客户端应用程序中的某些地方,我们希望维护此对象层次结构,但在其他地方,我们可能只想获取其中的一部分,例如,如果我们想查看和编辑房间中的桌子,但不关心关于大楼内的房间。由于 RIA 服务不会公开 Room 或 Desk 的 EntitySet,因此我们无法在不拉动父 Building 的情况下编辑其中任何一个。
是否有办法在 RIA 中维护这些关联,同时还允许编辑此层次结构的一部分,而不必拉入最顶层的父级?
We recently upgraded a Silverlight 4 app that was using RIA Services and EF 4.0 with EDMXs to RIA Services SP1 and EF 4.1 using POCOs. The upgrade was well worth while, but it appears that RIA is now playing differently with how it exposes Associated Entities on the Client.
For example say we have the following EF POCOs which are also our RIA Entities:
public class Building
{
public Building()
{
Rooms = new List<Room>();
}
[Key]
public int? BuildingID { get; set; }
public string Name {get; set;}
[Association("Building_1-*_Rooms", "BuildingID", "BuildingID")]
[Include]
[Composition]
public ICollection<Room> Rooms {get; set;}
}
public class Room
{
[Key]
public int? RoomID { get; set; }
[Required]
public int? BuildingID { get; set; }
public string Name {get; set;}
[Association("Building_1-*_Rooms", "BuildingID", "BuildingID", IsForeignKey= true)]
[Include]
public Building Building {get; set;}
[Association("Room_1-*_Desks", "RoomID", "RoomID")]
[Include]
[Composition]
public ICollection<Desk> Desks { get; set; }
}
public class Desk
{
[Key]
public int? DeskID { get; set; }
[Required]
public int? RoomID { get; set; }
public string Name { get; set; }
[Association("Room_1-*_Desks", "RoomID", "RoomID", IsForeignKey = true)]
[Include]
public Room Room { get; set; }
}
Building is the parent of Room and Room is the parent of Desk. The Association
attribute defines these relationships for RIA. We then expose these Entities with a simple service that has CRUD for all three entities
public class BuildingDomainService
{
var _context= new BuildingEFContext(); //Lets just say this is our EF Context that has all three types on it
public IQueryable<Buildings> GetBuildings()
{
return _context.Buildings.Include(x => x.Rooms.Select(y => y.Desks));
}
public IQueryable<Rooms> GetRooms()
{
return _context.Rooms.Include(x => x.Desks);
}
public IQueryable<Desk> GetDesks()
{
return _context.Desks;
}
//Empty Update and Insert Methods to allow editing on client
public void UpdateBuilding(Building building){}
public void InsertBuilding(Building building){}
public void DeleteBuilding(Building building){}
public void UpdateRoom(Room room){}
public void InsertRoom(Room room){}
public void DeleteRoom(Room room){}
public void UpdateDesk(Desk desk){}
public void InsertDesk (Desk desk){}
public void DeleteDesk (Desk desk){}
}
On the client the BuildingDomainContext that is generated from the BuildingDomainService has the three Exposed Methods (GetBuildingsQuery(), GetRoomsQuery(), and GetDesksQuery()), but only a single EntitySet of type Building, the service does not expose an EntitySet for Room or Desk.
In some places in our client app we want to maintain this object Hierarchy, but in others we may only want to get a slice of it, For example if we want to get look at and edit Desks in a Room, but don't care about Rooms in a Building. Because RIA Services does not expose an EntitySet for Room or Desk we cannot edit either of these without also pulling the parent Building.
Is there anyway to maintain these associations in RIA, but also allow for editing a part of this hierarchy, without having to pull in the top-most parent?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议阅读这篇文章 组合。添加 [Composition] 属性时,它会影响数据从服务器流向客户端的方式以及您可以独立编辑的实体。
I'd recommend reading this post on composition. When you add [Composition] attributes, it affects how the data flows from server to client as well as which entities you can edit independently.
也许使用 BuildingDomainContext.EntityContainer.GetEntitySet() 方法会公开您正在查找的
EntitySet
。您可以将其放入客户端BuildingDomainContext
的partial
实现中。例如:Perhaps using
BuildingDomainContext.EntityContainer.GetEntitySet<Room>()
method would expose theEntitySet
you are looking for. You could put this in thepartial
implementation of theBuildingDomainContext
on the client-side. For example: