使用引用发送EF对象后,WCF将崩溃 [英] WCF crashes after sending EF object with it's references

查看:96
本文介绍了使用引用发送EF对象后,WCF将崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个数据库,其中包括:

I have database with several tables, including:

CREATE TABLE [dbo].[Exam]
(
    [Id] INT NOT NULL PRIMARY KEY identity, 
    [Author id] INT NULL, 
    ...
    CONSTRAINT [FK_Exam_Author] FOREIGN KEY ([Author id]) REFERENCES [User]([Id]), 
)

CREATE TABLE [dbo].[User]
(
    [Id] INT NOT NULL PRIMARY KEY identity, 
    ...
)

我有 ADO。 NET 生成的数据库模型。

I have ADO.NET generated model of my database.

public partial class Exam
{
    public Exam()
    {
        ...
    }

    public int Id { get; set; }
    public Nullable<int> Author_id { get; set; }
    ...

    public virtual User User { get; set; }
    ...
}

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

    public int Id { get; set; }
    ...

    public virtual ICollection<Exam> Exam { get; set; }
    ...
}

我也有我的 Wcf服务中的GetExam 函数,它从数据库返回一个考试。

I have also GetExam function in my Wcf service, which returns one exam from database.

public Exam GetExam()
{
    var context = new GDBDatabaseEntities();
    context.Configuration.ProxyCreationEnabled = false;
    var exams = context.Exam;
    var exam = exams.FirstOrDefault();
    return exam;
}

禁用 ProxyCreationEnabled 必须通过 Wcf 发送考试

不幸的是代码返回我的考试空的用户字段( EF 自动生成此字段作为 FK_Exam_Author )...

Unfortunately above code returns me an exam with empty User field (EF generated this field automatically as a response for FK_Exam_Author)...

我试图加载用户属性 include function:

I've tried to load User attribute with Include function:

var exams = context.Exam.Include("User");

我有以下 Wcf 错误:


无法调用服务。可能原因:服务离线或无法访问;客户端配置与代理不匹配;现有代理无效。有关详细信息,请参阅堆栈跟踪。您可以尝试通过启动新的代理,还原到默认配置或刷新服务来恢复。

Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service.

Wcf 调试器显示检查对象正确(已加载用户依赖关系)

Just before return from Wcf debugger shows that Exam object looks properly (has loaded User dependency).

我认为这可能是由事实造成的,加载用户加载了他的考试的列表,已加载用户 ...(循环依赖)。

I think it could be caused by fact, that loaded User has loaded his Exams list, which has loaded User... (circular dependence).

我已经确定了与用户相同的问题。 - Wcf 适用于用户具有空的考试[] 属性,但是当我加载了用户的考试列表, Wcf 已崩溃...

I've exact the same problem with User - Wcf works for User with empty Exams[] property, but when I've loaded list of User's Exams, Wcf has crashed...

如何正确加载关系并通过 Wcf

How can I properly load relationship and send it via Wcf?

其他问题是如何 Wcf 知道如何序列化我的对象(当我使用 LINQ to SQL 它生成的类与 DataContract DataMember 属性,但实体框架只是不要

Additional question is how Wcf know how to serialize my objects (when I've used LINQ to SQL it generated classes with DataContract and DataMember attributes, but Entity Framework just don't do it.

循环依赖关系是一个问题,因为

It's the problem with circular dependences, because

public Exam GetExam()
{
    var context = new GDBDatabaseEntities();
    context.Configuration.ProxyCreationEnabled = false;
    var exams = context.Exam.Include("User");
    var exam = exams.FirstOrDefault();
    exam.User.Exam = null;
    return exam;
}

工作。

任何人都可以解释为什么 Include 函数是必需的加载1级依赖,我需要,但其他依赖加载无穷大?这很可怕...

Could anyone explain me why Include function is necessary for load 1-level dependences, which i need, but other dependences are loading for infinity? It's radiculous...

根据答案和雅虎加速您的网站的最佳实践第一条规则我决定为每个页面创建新对象在我的 Windows 8应用程序中,这将减少发送数据的数量,请求数量,并将让我避免发送冗余数据。

According to the answers and Yahoo's Best Practices for Speeding Up Your Web Site first rule I decided to create new object for every single Page in my Windows 8 application, which will reduce amount of sending data, number of requests and will let me avoid sending redundant data.

推荐答案

经过几次尝试,我很快放弃使用EF对象作为我的数据合同。正如您所发现的那样,循环依赖关系非常快速地打破了 DataContractSerializer 。另外,您的数据库对象可能包含不需要通过电子邮件发送给客户端的信息。

Having tried this several times, I quickly abandoned using EF objects as my data contracts. As you found, the circular dependency breaks the DataContractSerializer very quickly. Additionally, your database objects likely contain information that doesn't need to be sent across the wire to clients.

相反,为EF生成的对象创建类似的DataContract对象以供使用与WCF(没有循环依赖和其他问题),并在两者之间进行转换。例如:

Instead, create similar DataContract objects to the EF generated ones for use with WCF (without the circular dependencies and other problems), and translate between the two. For example:

[DataContract]
public class User
{
    [DataMember]
    public IEnumerable<Exam> Exams {get; set;}
}

[DataContract]
public class Exam
{
   [DataMember]
   public int Score {get; set;}
}

然后你只需要一个加载器函数,如:

Then you just need a loader function like:

IEnumerable<Contracts.User> GetAllUsers()
{
   foreach (DB.User in context.Users)
   {
       Contracts.User wcfUser = new Contracts.User();
       wcfUser.Exams = new List<Contracts.Exam>();
       foreach (DB.Exam exam in wcfUser.Exams)
          wcfUser.Exams.Add(new Contracts.Exam() { Score = exam.Score };

       yield return wcfUser;
   }
}

显然这扩展了你的代码库,但是避免让您的客户需要了解您的数据库对象,有助于保持网络流量下降,并导致更好的分离问题。

Obviously this expands your code-base quite a bit, but avoids having your clients needing to know about your database objects, helps keep your network traffic down, and results in a better separation of concerns.

希望能够回答您的问题如果我可以澄清一下,让我知道。

Hopefully that answers your question! Let me know if I can clarify anything.

这篇关于使用引用发送EF对象后,WCF将崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆