【问题标题】:Alternative to Using an Entity as a Parameter to an Invoke Method in WCF RIA Services在 WCF RIA 服务中使用实体作为调用方法的参数的替代方法
【发布时间】:2010-11-23 15:30:17
【问题描述】:

你好,你会的! StackOverflow 上的第一个问题! :-)

因此,场景如下:我们正在使用 Silverlight 4 开发一个 Web 应用程序,并为 Web 服务使用 WCF RIA Services 1.0 SP1 Beta。我在实体框架设计器中有我的实体,但我使用稍微修改过的 ADO.NET C# POCO 实体生成器模板来生成类。

我想做的是在域服务中使用具有以下签名的方法:

[EnableClientAccess]
public class ResultService : DomainService
{
    [Invoke]
    public SerializableResult CalculateResult(EntityOne e1, EntityTwo e2);
}

我通过其他服务中的查询将 EntityOne 和 EntityTwo 返回给客户端,如下所示:

[EnableClientAccess]
public class EntityOneService : DomainService
{
    public IQueryable<EntityOne> GetEntityOnes();
}

[EnableClientAccess]
public class EntityOneService : DomainService
{
    public IQueryable<EntityTwo> GetEntityTwos();
}

这些类在 Silverlight 项目中成功生成。 SerializableResult 没有有一个键。

当我尝试编译时,我收到以下错误:“名为 'CalculateResult' 的操作不符合所需的签名。参数类型必须是实体或复杂类型、复杂类型的集合或预定义的类型之一可序列化类型。”

在我的研究中,我发现最有用的信息是在 this post by Jeff Handley 的 cmets 中。

值得注意的是,彼得在评论中问道:

如果我的复杂对象具有 [Key] 属性,则会收到“不符合所需签名...”的编译错误。当我删除此属性时,我可以将该对象用作调用操作的参数。

杰夫的回应:

这是设计使然。复杂对象不能有 Key 属性。如果您有 Key,则该类将被视为实体。

因此,任何试图让我的方法发挥作用的进一步努力似乎都是徒劳的。但是,我想知道是否有其他人遇到过这个问题,以及他们做了什么来解决它。

非常感谢!

【问题讨论】:

  • SerializableResult 是否在客户端生成?我想知道这是否是我们的复杂类型识别中的一个错误,我们可能需要将 SerializableResult 类型作为实体上的属性显示出来,然后才能将其用作 Invoke 结果。
  • 如果我尝试:“[Invoke] public SerializableResult CalculateResult();”,SerializableResult 在客户端生成的。
  • 那听起来像是你实体的形状。 EntityOne 和 EntityTwo 是从 Entity 派生的吗?
  • 它们被生成作为派生自客户端项目中的实体,但它们不是派生自服务项目中的实体。

标签: silverlight entity-framework wcf-ria-services


【解决方案1】:

我有以下内容,它对我有用。

namespace BusinessApplication2.Web
{
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;

    [EnableClientAccess()]
    public class DomainService1 : DomainService
    {
        public IQueryable<EntityOne> GetEntityOnes()
        {
            return null;
        }

        public IQueryable<EntityTwo> GetEntityTwos()
        {
            return null;
        }

        [Invoke]
        public SerializableResult GetSerializableResult(EntityOne one, EntityTwo two)
        {
            return new SerializableResult() { Result = "It woooooorrrked!" };
        }
    }

    public class EntityOne
    {
        [Key]
        public int Id { get; set; }
    }

    public class EntityTwo
    {
        [Key]
        public int Id { get; set; }
    }

    public class SerializableResult
    {
        public string Result { get; set; }
    }
}

【讨论】:

  • 所以我在 DomainService 中添加了两个虚拟查询方法(返回 IQueryable 和 IQueryable以及CalculateResult 方法,现在编译!为什么不按原路编译?
  • 这可能是我们的“共享实体”功能中的一个错误,它允许您跨域服务使用实体类型。我会将其归档并让您知道这是设计使然还是实际上是错误。
  • 正如亚当所说,这实际上是设计使然,而不是错误。
  • 谢谢!!!早些时候我只有一个不符合的设置方法(失败并显示消息“名为'XXX'的操作不符合所需的签名。参数类型必须是实体类型或预定义的可序列化类型之一”)通过添加一个虚拟根据 Jeff Handley 的示例查询方法,我能够成功编译我的代码。
【解决方案2】:

非常感谢 Jeff Handley 先生和 Dinesh Kulkarni 先生的回答(通过Twitter)。

为了将实体用作调用方法中的参数,该实体必须通过存在于同一 DomainService 中的查询方法公开。这个限制的目的是

“每个域服务都需要能够独立存在。”

通过添加两个虚拟 Query 方法(请参阅 Jeff 的答案以获取示例),我能够编译我的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多