2012-02-13 118 views
0

我一直在网上搜索一种方法来解决我的问题,我没有任何运气。我正在开发一个Silverlight商务类应用程序,并尝试使用RIA服务。我成功地加载和保存没有任何重大问题的实体,但是当我的应用程序第一次加载时,我需要加载我所谓的“值列表”。Silverlight/RIA服务/ EF - 自定义对象

我的值列表是独立的实体,大概5个左右,由Id(键)和Value组成,它们用于填充combobox和autocompletebox之类的东西。我可以单独查询每一个,但是我宁愿在一次查询中一次加载所有值列表,以加快速度,因为每条记录少于15条记录。我试图开发一个自定义类返回所有这些,它看起来像这样...

<DataContract(IsReference:=True)> 
<KnownType(GetType(ValueList1Item))> 
<KnownType(GetType(ValueList2Item))> 
<KnownType(GetType(ValueList3Item))> 
Partial Public Class ValueLists 

    <DataMember()> 
    Public Property ValueList1 AS List(Of ValueList1Item) 

    <DataMember()> 
    Public Property ValueList2 AS List(Of ValueList2Item) 

    <DataMember()> 
    Public Property ValueList3 AS List(Of ValueList3Item) 
End Class 

我已经试过许多方法来实现服务的方法,其中一个看起来是这样的...

Public Function GetValueLists() As ValueLists 
     Dim ret As ValueLists = New ValueLists 

     ret.ValueList1 = (From v1 In ObjectContext.ValueList1Items 
          Select v1).ToList 

     ret.ValueList2 = (From v2 In ObjectContext.ValueList1Items 
          Select v2).ToList 

     ret.ValueList3 = (From v3 In ObjectContext.ValueList3Items 
          Select v3).ToList 

     Return ret 
    End Function 

我也试过返回一个IQueryable(ValueLists)。无论我尝试过什么,每当我尝试使用自定义类型时,都无法将该方法公开给客户端。 RIA Services甚至有可能做这样的事情还是尚未成熟?我知道我在过去用直WCF完成了这一点,但它显然有更多的工作。

由于提前, 凯西

回答

0

(对不起我的英文不好)

我以前尝试这样做,它确实没有工作。如果你为ValueList1创建了一个新类,它就可以工作。但是,如果您使用具有[Key]属性的类,出于某种原因,它不会生成(该属性不会出现在客户端)。所以,一个解决办法是像ReadOnlyValueList1创建类并返回它:

ret.ValueList1 = (from v1 In ObjectContext.ValueList1Items 
         select new ReadOnlyValueList1() 
         { 
          Prop1 = v1.Prop1, 
          Prop2 = v1.Prop2, 
         }).ToList(); 

(对不起,C#代码,可能这是在VB中有少许差别)

它任何意义,因为你不希望所有EF的东西(跟踪等)只是为了绑定一些列表和组合。

+0

谢谢你的回复狮子座。只要我有机会,我会尝试一下,看看它是否有效。如果我继续遇到像这样的问题,我可能会很快倾倒RIA服务,并直接进入常规的WCF实现。我知道WCF是更多的工作,但它肯定是更灵活,这是很好的。在这一点上,我认为RIA Services不是复杂程度相当高的应用程序的最佳解决方案,但也许我错了。 – Casey 2012-02-13 16:05:05

+0

那么我对这个狮子座还没有任何运气。我真的不希望实体只能被读取,因为我将有一个“系统”页面,用户可以编辑这些值列表。 – Casey 2012-02-16 12:12:42

0

你应该能够做到这一点没有问题,而是传递一个对象到RIA服务客户端时,你需要指定一个[关键]这是保证所有喜欢的对象之间唯一的。这是由于RIA服务处理缓存客户端上的这些对象的方式。此外,您的ValueList1Item,ValueList2Item等需要可序列化

当这样设置时,RIA服务会将你的服务器POCO对象变成客户端实体对象。您将遇到的唯一问题是您必须手动处理任何CUD操作。如果它是您传递给客户端的只读数据,则无需担心。

+0

正如Derreck所建议的,我将Key属性添加到DTO的Id属性中,该属性只是一个随机生成的数字。虽然这次编译正确,但它仍然不按照fiddler传输数据。我认为在这一点上,我将倾销RIA服务并实现标准的WCF实施。是的,开发需要更长的时间,但灵活性要好很多,我已经了解了WCF,所以最终它可能会更流畅,甚至更快。到目前为止,我不是IQueryable的粉丝,我知道WCF我可以使用没有问题的列表。 – Casey 2012-02-16 14:20:23

+0

如果您使用该方法,我不会打扰使用IQueryables。只需使用数组或列表。让它工作并不容易,所以我可以理解你的挫败感。我一直在使用RIA服务已经有一年多的时间了,我认为有很多事情需要解决。如果你碰巧使用数组或列表而不是IQueryable来给它另一个镜头,让我知道它是如何工作的。 – 2012-02-17 15:13:30

0

嗯,我设法得到了一点点。将Key添加到返回对象的Id属性中,至少使它成功编译,但使用fiddler查看结果我可以看到对象中没有任何内容。我猜这是这种序列化问题。

我从我的模型生成的另一个实体类的副本构造了我的返回对象(dto),以确保我没有错过任何东西。然后我评论了所有更改跟踪,以确保它不会造成任何问题。下面是类:

<DataContract(IsReference:=True)> _ 
<KnownType(GetType(ValueList1Item))> _ 
<KnownType(GetType(ValueList2Item))> _ 
Partial Public Class ValueLists 

#Region "Primitive Properties" 

    <DataMember()> _ 
    <Key()> _ 
    Public Property Id() As Long 
     Get 
      Return _id 
     End Get 
     Set(ByVal value As Long) 
      If Not Equals(_id, value) Then 
       _id = value 
      End If 
     End Set 
    End Property 

    Private _id As Long 



    <DataMember()> _ 
    Public Property ValueList1() As List(Of ValueList1Item) 
     Get 
      Return _valueList1 
     End Get 
     Set(ByVal value As List(Of ValueList1Item)) 
      If Not Equals(_valueList1, value) Then     
       _valueList1 = value    
      End If 
     End Set 
    End Property 

    Private _valueList1 As List(Of ValueList1Item) 



    <DataMember()> _ 
    Public Property ValueList2() As List(Of ValueList2Item) 
     Get 
      Return _valueList2 
     End Get 
     Set(ByVal value As List(Of ValueList2Item)) 
      If Not Equals(_valueList2, value) Then     
       _valueList2 = value    
      End If 
     End Set 
    End Property 

    Private _valueList2 As List(Of ValueList2Item) 

#End Region 
End Class 

而且我使用的构造和返回对象看起来像这样的方法......

Public Function GetValueLists() As ValueLists 
     Dim ret As ValueLists = New ValueLists 

     ret.Id = RandomNumber(1, 100000000) 

     ret.ValueList1 = (From vli1 In ObjectContext.ValueList1Items 
           Select vli1).ToList() 

     ret.ValueList2 = (From vli2 In ObjectContext.ValueList2Items 
             Select vli2).ToList() 


     Return ret 
    End Function 

跟踪这种方法表明它实际上是工作的罚款。我可以看到正确填充的所有值列表项,它只是永远不会离开服务器。这导致我相信这是某种序列化问题。