2012-05-11 35 views
0

我正在使用EF 4.3代码优先使用WCF数据服务(刚刚发布的5.0)通过HTTP公开数据 我发现如果我从浏览器调用服务操作我能够获得相关实体,但是当我在客户端应用程序中使用服务操作时,我无法找回相关实体。 我一直在研究这isuse它似乎EF启用延迟加载whn使用虚拟关键词时引用一个ICollection,这一些如何防止WCF数据服务returing realted实体 - 这是真的 如果我在本地浏览,并把一个休息指向我的getUsersByName方法我可以看到相关的组实体,但是当它通过电缆连接到客户端应用程序时,缺少gropup实体。 有没有配置来启用它。WCF数据服务 - 服务操作不返回相关的原因

感谢 如

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

回答

0

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

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

1

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

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

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