0

我首先使用 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;
        }
4

2 回答 2

1

Actually regardless of what you do on the server side with the entity WCF DS will not return expanded entities by default. It's a feature. The reason is size of the message on the wire. The client can request this behavior though (and that should work without making any modifications to the EF entities on the server side).

Let's assume you have a service operation GetProducts. You can issue a query like ~/GetProducts?$expand=Category which will include the Category entities in the result.

You also noted that the client doesn't get to see these, but you do see them in the browser. So are you already using the $expand? If that's the case the problem is solely on the client. Make sure that you request the results using the $expand on the client as well (depends on what code you're using, there's an Expand method in the LINQ on the client for this). And then you can use Fiddler to see if the client actually gets the results back the way you want. If that's the case and you still don't get the results in your client code, it might be due to MergeOptions. Try setting DataServiceContext.MergeOption to OverwriteChanges and try again (but be sure that you're aware of what this setting does).

于 2012-05-11T08:59:20.930 回答
0

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

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

于 2012-05-11T04:00:38.890 回答