WCF数据服务 - 不返回相关实体的服务操作

时间:2012-05-11 01:38:41

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

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

由于 例如

 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;
        }

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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

使用延迟加载与序列化几乎是不可能的,因为当序列化程序访问导航属性时,将加载相关实体。这将导致加载整个数据库。因此,您需要禁用延迟加载并使用Include加载您想要的任何内容,或者您​​可以在启用延迟加载的情况下使用某些DTO。