2011-06-08 49 views
2

我們最近使用POCO將使用RIA Services和EF 4.0以及EDMX的Silverlight 4應用程序升級到RIA Services SP1和EF 4.1。這次升級非常值得,但看起來RIA現在玩的方式與它在客戶端暴露相關實體的方式不同。公開RIA服務SP1和EF 4.1中的關聯實體POCO

比如講我們有以下EF波蘇斯這也是我們的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; } 
} 

樓是客房的家長和房間服務檯的父母。 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服務不公開客房或辦公桌的實體集,因此我們無法在不拉動父建築物的情況下編輯這些實體集。

有沒有辦法在RIA中維護這些關聯,還允許編輯此層次結構的一部分,而不必拉入最頂層的父級?

回答

3

我推薦閱讀這篇文章composition。添加[合成]屬性時,會影響數據從服務器流向客戶端的方式以及可以獨立編輯的實體。

+0

感謝鏈接Kyle。看起來RIA不支持這種靈活的層次結構。聽起來好像如果通過「Composition」屬性建立父子關係,則無法編輯父子獨立子。我很欣賞閱讀材料,至少我有一個明確的答案! – jstromwick 2011-06-09 20:35:05

+1

有趣的是,我能夠創建第二個父類,它本質上是一個包含具有「Composition」屬性的子對象集合的虛擬類。這使我可以添加新的子對象而不需要其他的層次結構。看起來,將組合屬性添加到子集合允許該對象控制集合,而不管該子類型是否已經具有另一個父對象。 – jstromwick 2011-09-20 22:43:00

0

也許使用BuildingDomainContext.EntityContainer.GetEntitySet<Room>()方法會暴露EntitySet您正在尋找。你可以把它放在客戶端的BuildingDomainContextpartial實現中。例如:

public partial class BuildingDomainContext 
{ 
    public EntitySet<Room> Rooms 
    { 
     get 
     { 
      return EntityContainer.GetEntitySet<Room>(); 
     } 
    } 
} 
+0

哇哇。我測試了這一點,但它不起作用,因爲它看起來像RIA有一個要求,如果沒有加載父實體,具有父(通過'Composition'屬性)的實體不能被更新。嘗試更新未加載父進程的子進程時,如果提交System.ServiceModel.DomainServices.Client.DomainOperationException:提交操作失敗,則會提供以下DomainException。無效的ChangeSet:類型爲'Dummy.Web.Services.Room'的子實體不能獨立於其父級更新。' – jstromwick 2011-06-09 20:29:08