【问题标题】:WCF Data services - service operations not returning related entiitiesWCF 数据服务 - 服务操作不返回相关实体
【发布时间】:2012-05-11 01:38:40
【问题描述】:

我首先使用 EF 4.3 代码并使用 WCF 数据服务(5.0 刚刚发布)通过 HTTP 公开数据 我发现如果我从浏览器调用服务操作,我可以取回相关实体,但是当我在客户端应用程序中使用服务操作时,我没有取回相关实体。 我一直在研究这个问题,似乎 EF 在引用 ICollection 时使用虚拟关键字启用延迟加载,这在某种程度上阻止了 WCF 数据服务返回实际实体 - 这是真的吗 如果我在本地浏览并在我的 getUsersByName 方法上放置一个断点,我可以看到相关的组实体,但是当它通过线路连接到客户端应用程序时,组实体丢失了。 是否有启用此功能的配置。

谢谢 例如

 public partial class Group
    {
        public Group()
        {
            this.Users = new HashSet<User>();           
        }

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int GroupID { get; set; }

        [Required(ErrorMessage = "Please enter a group name")]
        [StringLength(50, ErrorMessage = "The group name is too long")]
        public string GroupName { get; set; }

        [Required]
        public System.DateTime CreatedDate { get; set; }

        [Required]
        public bool Admin { get; set; }

        public virtual ICollection<User> Users { get; set; }

    }
    public partial class User
    {
        public User()
        {
            this.Groups = new HashSet<Group>();
        }


        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int UserID { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        [Required(ErrorMessage="Please enter a username")]
        [StringLength(50,ErrorMessage="Username is too long")]
        public string UserName { get; set; }

        [Required(ErrorMessage="Please enter an email address")]
        [RegularExpression(".+\\@.+\\..+",ErrorMessage="Please enter a valid email address")]
        public string Email { get; set; }

        [Required]
        public System.DateTime CreatedDate { get; set; }

        public virtual ICollection<Group> Groups { get; set; }
    }

    public partial class TestContext : DbContext
    {
        public Test()
            : base("name=TestEntities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Tell Code First to ignore PluralizingTableName convention
            // If you keep this convention then the generated tables will have pluralized names.
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        }

        public DbSet<Group> Groups { get; set; }
        public DbSet<User> Users { get; set; }

    }

    [ServiceBehavior(IncludeExceptionDetailInFaults=true)]
    [JSONPSupportBehavior]
    public class TestSVC : DataService<TestContext>
    {

        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
            config.SetServiceActionAccessRule("*", ServiceActionRights.Invoke);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
            config.UseVerboseErrors = true;
        }        

        [WebGet]
        public User GetUserByName(string userName)
        {
            var user = (from u in this.CurrentDataSource.Users
                       where u.UserName == userName
                       select u).FirstOrDefault();

            return user;
        }

【问题讨论】:

    标签: entity-framework ef-code-first wcf-data-services


    【解决方案1】:

    实际上,无论您在服务器端使用实体 WCF DS 做什么,默认情况下都不会返回展开的实体。这是一个特点。原因是线路上消息的大小。 但是,客户端可以请求此行为(并且无需对服务器端的 EF 实体进行任何修改即可工作)。

    假设您有一个服务操作 GetProducts。您可以发出类似 ~/GetProducts?$expand=Category 的查询,它将在结果中包含 Category 实体。

    您还注意到客户端看不到这些,但您可以在浏览器中看到它们。那么你已经在使用 $expand 了吗?如果是这种情况,则问题仅出在客户端上。确保您也使用客户端上的 $expand 请求结果(取决于您使用的代码,客户端上的 LINQ 中有一个 Expand 方法)。然后您可以使用 Fiddler 查看客户端是否真的以您想要的方式获取结果。如果是这种情况并且您仍然没有在客户端代码中获得结果,则可能是由于 MergeOptions。尝试将 DataServiceContext.MergeOption 设置为 OverwriteChanges 并重试(但请确保您了解此设置的作用)。

    【讨论】:

      【解决方案2】:

      尝试在构造函数中删除导航属性的初始化,因为这会导致代理对象出现问题。

      几乎不可能在序列化中使用延迟加载,因为当序列化程序访问导航属性时,相关实体将被加载。这将导致加载整个数据库。所以你需要禁用延迟加载并使用Include 来加载你想要的任何东西,或者你可以使用一些启用延迟加载的DTO。

      【讨论】:

        猜你喜欢
        • 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
        相关资源
        最近更新 更多