【问题标题】:Access many to one Entity Framework model properties in RenderAction view using lambda expressions使用 lambda 表达式在 RenderAction 视图中访问多对一实体框架模型属性
【发布时间】:2015-09-23 15:12:48
【问题描述】:

我尝试在 Render 操作中访问模型 (FilePath) 的属性,但没有成功。

我有这些模型:

public class Offer
{
 public int OfferID { get; set; }
 public string Reference { get; set; }
 public string Title { get; set; }

 public virtual ICollection<FilePath> FilePaths { get; set; }
}

public class FilePath
{
 public int FilePathId { get; set; }
 public string FileName { get; set; }
 public virtual Offer Offer { get; set; }
}

在控制器报价中:

public PartialViewResult Category()
{
 var offers = db.Offers
 .Include(i => i.FilePaths)
 // i tried with .Include(“FilePaths”) with no sucess
 .ToList();
  return PartialView("_OfferBoxList", offers);
}

显示为:

@{Html.RenderAction("Category", "Offer");}

问题出在部分动作视图中:

@foreach (var item in Model)
{
 @item.Title // This work
 @item.FilePath.FileName // This NOT work
}

输出错误:

“System.Data.Entity.DynamicProxies.Offer_278BF6A1F89FB9514329AC922E992AEBD19368D66A4460B6BEBA1BB2256CAFC3”不包含“FilePath”的定义

感谢您的帮助。

【问题讨论】:

  • 如果你关闭延迟加载,我认为它会解析为类型,而不是代理。但是,你真的不应该将你的实体加载到视图中。我通常创建 DTO,而不是仅在查询中塑造数据,但也可用作 dataItems/dataSource 用于这些目的..
  • 另外,FilePaths(复数)是Offer的属性,它是Collection&lt;FilePath&gt;..@item.FilePath(单数)甚至不存在这个代码sn-p ..

标签: c# entity-framework lambda renderaction


【解决方案1】:

每个Offer 都有一个FilePath 实例列表(ICollection&lt;FilePath&gt; FilePaths),因此您不能只访问Offer.FilePath.FileName 属性,您必须获取例如第一个(取决于您需要什么) ,使用类似的东西:

@foreach (var item in Model)
{
     @item.Title // This work
     @item.FilePaths.First().FileName // Take the first FilePath object from the collection
}

【讨论】:

    【解决方案2】:

    您真的不应该将实体加载到视图中..

    我通常出于多种目的创建数据传输对象 (DTO)。它不仅帮助我塑造查询表达式 (IQueryable&lt;T&gt;),而且我还使用了 Concert 类型(而不是生成的动态代理类类型 - 就像您在运行时异常中看到的类型)在控制属性中,如dataItemdataSource,它们经常用于运行时可绑定的动态/反射控件(网格、列表视图)中......

    注意 可以通过声明并将您自己的DbContextConfiguration 实例传递给EntityFramework 来禁用生成的动态代理类型;但是,这样做会影响 EntityFramework 支持的功能。


    public class OfferDTO
    {
        public int OfferID { get; set; }
        public string Reference { get; set; }
        public string Title { get; set; }
        public IEnumerable<string> FileNames { get; set; }
    }
    

    您的控制器功能将如下所示:

    public PartialViewResult Category()
    {
        var offers = db.Offers.Select<Offer, OfferDTO>( (entity) => new OfferDTO() {
            OfferID = entity.OfferID,
            Reference = entity.Reference,
            Title = entity.Title,
            FileNames = entity.FilePaths.Select<FilePath, string>( filePath => filePath.FileName).AsEnumerable()
        });
    
        return PartialView("_OfferBoxList", offers.ToList());
    }
    

    那么,

    @{Html.RenderAction("Category", "OfferDTO");}
    
    @foreach (var item in Model) // Model is IEnumerable<OfferDTO>
    {
        @item.Title 
        @item.FileNames.First()
    }
    

    另外,

    您可以创建一个IQueryable&lt;IQueryable&lt;TEntityDTO&gt;&gt; 以满足您的目的并对其执行 SelectMany 以使结果变平。

    public class OfferTitleFilenameDTO
    {
        public string Title {get;set;}
        public string Filename {get;set;}
    }
    
    public PartialViewResult Category()
    {
        var offers = db.Offers.Select<Offer, IQueryable<OfferTitleFilenameDTO>>( (entity) => entity.FilePaths.Select<FilePath, OfferTitleFilenameDTO>(filePath => new OfferTitleFilenameDTO() {
                Filename = filePath.FileName,
                Title = entity.Title
            })
        });
    
        return PartialView("_OfferBoxList", offers.SelectMany(dtos => dtos));
    }
    

    那么,

    @{Html.RenderAction("Category", "OfferTitleFilenameDTO");}
    
    @foreach (var item in Model) // Model is IEnumerable<OfferTitleFilenameDTO>
    {
        @item.Title 
        @item.Filename 
    }
    

    【讨论】:

    • 您的 include 语句在这里似乎是不必要的。。我认为,一般来说,当您尝试从其他查询路径指定查询路径时使用包含 .. 并且因为您只有 1 个导航财产..您只有 1 个查询路径提供..
    • 这些样本假定db.OffersIQueryable&lt;Offer&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多