【问题标题】:Unit of Work, LazyLoading Disabled, Generic Repository, IncludeMultiple<T>, Http 500 error工作单元、LazyLoading 已禁用、通用存储库、IncludeMultiple<T>、Http 500 错误
【发布时间】:2012-11-03 17:37:48
【问题描述】:
  1. 我有一个与 Model 关联的 Vehicle,Model 与 Make 有关联。

  2. 这是我的通用存储库,与我的项目中的 LazyLoadingEnabled = false 关联:

    public IQueryable<T> IncludeMultiple<T1>(params Expression<Func<T, object>>[] associations) where T1 : class
    {
        var source = (IQueryable<T>)DbContext.Set<T>();
        if (associations != null)
        {
            foreach (Expression<Func<T, object>> path in associations)
                source = DbExtensions.Include<T, object>(source, path);
        }
        return source;
    }
    
  3. 在我的 api 控制器中,我使用的是工作单元模式。这是我的 GetAll 方法:

    public IEnumerable<Vehicle> GetAll()
    {
      var vehicles = Uow.VehicleRepository.IncludeMultiple<Vehicle>(c => c.VehicleModel).ToList();
      return vehicles;
    }
    

一切正常,Json 检索 Vehicle 类数据以及相关的 VehicleModel 类数据。

但是,Vehicle 与 VehicleMake 没有直接关联,只有 VehicleModel 有。现在,如果我的 GetAll 方法有这个:

    public IEnumerable<Vehicle> GetAll()
    {
      var vehicles = Uow.VehicleRepository.IncludeMultiple<Vehicle>(c => c.VehicleModel, c => c.VehicleModel.VehicleMake).ToList();
      return vehicles;
    }

虽然我在调试中看到车辆确实具有车辆及其相关的 VehicleModel 和 VehicleMake 数据,但它在 Fiddler 中返回 Http 500 错误。


更新:


在 Vehicle 中添加了另一个名为“Test”的关联,GetAll 方法为:

(c => c.VehicleModel, c => c.Test)

没有错误,所有数据都是通过 fiddler 返回的。因此,“非直接关联”(即 Vehicle -> VehicleMake)似乎是导致错误的原因。


问题:


在没有收到 Http 500 错误的情况下,检索相关车辆数据及其关联类的数据并将其返回给 Json 的正确方法是什么?

【问题讨论】:

  • 你不能调试它来找到抛出的精确异常吗? “Fiddler 中的 Http 500 错误”并不是最好的错误描述。

标签: entity-framework api repository-pattern unit-of-work


【解决方案1】:

*已解决 *


这行得通:

  public HttpResponseMessage GetAll()
  {
      var vehicles = from data in  Uow.VehicleRepository.IncludeMultiple<Vehicle>(c => c.VehicleModel,c => c.VehicleModel.VehicleMake)
                         select new 
                             {
                                VehDesc = data.Description,
                                VehVIN = data.VIN,
                                VehTransmissionType = data.TransmissionType,
                                VehFuelType = data.FuelType,
                                VehYear = data.Year,
                                VehMileage = data.Mileage,
                                VehCylinderSize = data.CylinderSize,
                                VehEngineSize = data.EngineSize,
                                VehVehicleModel = data.VehicleModel.Name,
                                VehMakeName = data.VehicleModel.VehicleMake.Name
                             };
      return Request.CreateResponse(HttpStatusCode.OK, vehicles);
  }

基本上,

 1. I used an HttpResponseMessage as my return type;

 2. I used projection to create an anonymous type;

为什么我必须这样做?

据我所知,问题集中在 JSON 收到 VehicleModel 和 VehicleMake 的“循环”返回。也就是说,VehicleModel 与 VehicleMake 有关联,而 VehicleMake 有一个 VehicleModel 的集合。当我查看调试代码时,我可以看到 VehicleModel 到 VehicleMake 到 VehicleModel 等的级联,等等等等,所以对我来说这意味着它是循环的。

如果有人知道不使用匿名类型或从我的导航属性中删除虚拟关键字的更好方法,我当然想知道。但这确实有效。

FinalNote:确保不要在匿名类型中使用模型的属性名称,即将属性“TransmissionType”替换为“VehTransmissionType”。

【讨论】:

  • 在我看来,这不仅是一种解决方法,而且实际上是加载投影对象(匿名或命名)而不是完整实体进行序列化的更好方法。您应该接受您的答案:) BTW:您可以从上面的代码中删除.IncludeMultiple,因为在您进行投影时,EF 无论如何都会忽略Include。 BTW2:您不需要删除 virtual 关键字来禁用延迟加载和代理创建。您可以使用:context.Configuration.ProxyCreationEnabled = false(或...LazyLoadingEnabled = false)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
相关资源
最近更新 更多