Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 每当向属性添加虚拟对象时发生序列化异常_C#_Entity Framework_Asp.net Web Api - Fatal编程技术网

C# 每当向属性添加虚拟对象时发生序列化异常

C# 每当向属性添加虚拟对象时发生序列化异常,c#,entity-framework,asp.net-web-api,C#,Entity Framework,Asp.net Web Api,我的web api项目中有一个报告类: [KnownType(typeof(Employee))] [DataContract] public class Report { [DataMember] public int Id { get; set; } public string ManagerId { get; set; } public string EmployeeId { get; set; } [DataMember] public

我的web api项目中有一个
报告
类:

[KnownType(typeof(Employee))]
[DataContract]
public class Report
{
    [DataMember]
    public int Id { get; set; }

    public string ManagerId { get; set; }
    public string EmployeeId { get; set; }

    [DataMember]
    public virtual Employee Manager { get; set; }

    [DataMember]
    public virtual Employee Employee { get; set; }
}
如果
virtual
在方法签名中,我会得到以下异常:

不应键入“System.Data.Entity.DynamicProxies.Report”和数据合同名称为“Report”的“System.Data.Entity.DynamicProxies.Report”和“Report”的“Report”。考虑使用DATACONTRORTCORDEVER或将未知类型的任何类型添加到已知类型的列表中——例如,使用NoNyType属性或将它们添加到传递给DATACONTROTTRORIGLASER的已知类型列表中。 如果不是每件事都有效的话。我错过了什么


编辑以包含对象检索代码 高级控制器

[ResponseType(typeof(IEnumerable<Report>))]
public IHttpActionResult GetLogs([FromUri] string id)
{
    return Ok(_loggingService.GetReportsByEmployeeId(id));
}
[ResponseType(typeof(IEnumerable))]
公共IHttpActionResult GetLogs([FromUri]字符串id)
{
返回Ok(_loggingService.GetReportsByEmployeeId(id));
}
服务

public IQueryable<Report> GetReportsByEmployeeId(string employeeId)
{
    return _reports.GetAll().Where(x => x.ManagerId.Equals(employeeId) || x.EmployeeId.Equals(employeeId));
}
public IQueryable GetReportsByEmployeeId(字符串employeeId)
{
return _reports.GetAll(),其中(x=>x.ManagerId.Equals(employeeId)| | x.employeeId.Equals(employeeId));
}
存储库

public IQueryable<T> GetAll()
{
    return _dbSet;
}
public IQueryable GetAll()
{
返回_dbSet;
}

您可能正在使用实体框架或类似的ORM检索此对象

当您没有任何虚拟属性时,ORM可以安全地使用您类型的实例。但是,当您拥有虚拟属性时,ORM必须使用自己的类型以支持延迟加载,这就是为什么您看到序列化程序抱怨它无法序列化类型“DynamicProxies”

要避免这种情况,请将域模型与序列化模型分开,并在调用中选择“返回序列化模型的实例”

或者,关闭ORM中的延迟加载(不推荐)

编辑:添加评论中讨论的示例

如前所述,域模型(用于与数据库交互的数据的对象表示)和业务模型(用于业务逻辑的数据的对象表示)在理想情况下应该分开。此外,服务之外的任何内容都不应该直接接触域模型,因为这样做可能会触发意外的延迟负载、模糊代码库中的职责或其他不愉快的结果

顺便说一句,这种分离可以避免你遇到的问题。下面的示例中,当然可以随意更改名称空间和类型名称

商业模式

namespace MyCompany.MyProject.BusinessModels
{
    [KnownType(typeof(Employee))]
    [DataContract]
    public class Report
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public virtual Employee Manager { get; set; }

        [DataMember]
        public virtual Employee Employee { get; set; }
    }
}
namespace MyCompany.MyProject.DomainModels
{
    // this separation may seem like overkill, but when you come to
    // want different business models than your domain models, or to decorate
    // this model with Entity Framework specific attributes, you'll be glad
    // for the separation.
    public class Report
    {
        public int Id { get; set; }

        public virtual Employee Manager { get; set; }

        public virtual Employee Employee { get; set; }
    }
}
域模型

namespace MyCompany.MyProject.BusinessModels
{
    [KnownType(typeof(Employee))]
    [DataContract]
    public class Report
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public virtual Employee Manager { get; set; }

        [DataMember]
        public virtual Employee Employee { get; set; }
    }
}
namespace MyCompany.MyProject.DomainModels
{
    // this separation may seem like overkill, but when you come to
    // want different business models than your domain models, or to decorate
    // this model with Entity Framework specific attributes, you'll be glad
    // for the separation.
    public class Report
    {
        public int Id { get; set; }

        public virtual Employee Manager { get; set; }

        public virtual Employee Employee { get; set; }
    }
}
服务

public IQueryable<BusinessModels.Report> GetReportsByEmployeeId(string employeeId)
{
    return _reports // _reports is a collection of Type DomainModels.Report
            .GetAll()
            .Where(x => 
                 x.ManagerId.Equals(employeeId) 
                 || x.EmployeeId.Equals(employeeId))
            .Select(s =>
               new BusinessModels.Report
               {
                    Id = s.Id,
                    Employee = s.Employee,
                    Manager = s.Manager
               })
            .ToList(); 
            // We don't want database access happening outside of the service. 
            // ToList() executes the SQL *now* rather than waiting until 
            // the first time you enumerate the result.
}
public IQueryable GetReportsByEmployeeId(字符串employeeId)
{
return _reports//_reports是DomainModels.Report类型的集合
.GetAll()
.其中(x=>
x、 ManagerId.Equals(employeeId)
||x.EmployeeId等于(EmployeeId))
。选择(s=>
新商业模式。报告
{
Id=s.Id,
雇员=美国雇员,
经理
})
.ToList();
//我们不希望数据库访问发生在服务之外。
//ToList()立即执行SQL*而不是等到
//第一次枚举结果时。
}

您的意思是像DTO一样,还是可以给出/链接到一个示例?我不知道如何实现这种分离。如果你用获取对象的代码更新你的问题,我会在我的桌面上更新我的答案。如果需要进一步澄清,请告诉我。非常感谢。这是很棒的东西。