如何在Entity Framework正在填充的另一个对象内部排序List <t>属性

时间:2015-05-01 18:00:36

标签: c# asp.net-mvc entity-framework

我试图找出确保另一个对象中的对象列表始终以相同方式排序的最佳方法。

我目前有我的班级Jobsite:

public class Jobsite
{
    #region Class Properties
    [Key]
    public long Id { get; set; }
    ...

    private DateTime? _createdOn;
    public DateTime CreatedOn
    {
        get
        {
            if (_createdOn.HasValue)
                return _createdOn.Value;
            else
                return DateTime.UtcNow;
        }
        set { _createdOn = value; }
    }

    public long? CreatedById { get; set; }
    #endregion


    #region Navigation Properties
    [ForeignKey("CustomerId")]
    public Customer Customer { get; set; }

    public List<Job> Jobs { get; set; }

    public List<JobsiteNote> JobsiteNotes { get; set; }
    #endregion
}

这个类由实体框架填充,如下所示:

public class EFJobsiteRepository : IJobsiteRepository
{
    private EFDbContext _context = new EFDbContext();

    public IQueryable<Jobsite> Jobsites
    {
        get
        {
            return _context.Jobsite
                .Include("JobsiteNotes.CreatedBy")
                .Include("Customer")
                .Include("Jobs.JobType");
        }
    }

    public void Save(Jobsite jobsite)
    {
        if (jobsite.Id == 0)
        {
            _context.Jobsite.Add(jobsite);
        }
        else
        {
            _context.Entry(jobsite).State = EntityState.Modified;
        }

        _context.SaveChanges();
    }
}

非常标准的东西。一切正常。在我看来,我想列出所有“JobsiteNotes”,但是我希望它们被命令下载

现在,我认为:

<div>
    @foreach (var note in Model.Jobsite.JobsiteNotes.OrderByDescending(x => x.CreatedOn))
    {
        @Html.Partial("Note", note)
    }
</div>

这很好用,但我认为理想情况下,这个排序应该在该列表的getter / setter中完成。这样,我不必在每个我想要使用它们的视图中明确地排序注释列表。

我想我可以做这样的事情:

private List<JobsiteNote> _jobsiteNotes;
    public List<JobsiteNote> JobsiteNotes 
    { 
        get
        {
            return _jobsiteNotes.OrderByDescending(x => x.CreatedOn).ToList();
        }
        set
        {
            _jobsiteNotes = value;
        }
    }

然而,列表是空的...这可能是愚蠢的,但为什么我不能在这里添加订单逻辑?

修改 Jobsite类正在控制器中初始化。我正在使用Ninject库进行依赖注入。

以下代码填充了Jobsite类中的_jobsiteNotes列表。 EF为我做了这一切。当我从存储库中获取工作现场时,它会将其与所有与之关联的注释返回。

public class JobsiteController : Controller
{
    private IJobsiteRepository _jobsiteRepository;

    public JobsiteController(IJobsiteRepository jobsiteRepo)
    {
        _jobsiteRepository = jobsiteRepo;
    }

    // GET: Jobsite
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Manage(long id)
    {
        var jobsite = _jobsiteRepository.Jobsites.FirstOrDefault(x => x.Id == id);

        var model = new JobsiteViewModel
        {
            ActiveJobId = jobsite.Jobs.FirstOrDefault().Id,
            Jobsite = jobsite
        };

        return View(model);
    }
}

编辑2 我发现了这个问题:How to include sorted navigation properties with Entity Framework

我正在尝试订购导航属性。但是,该解决方案似乎不是最好的方法。

当Entity Framework填充JobsiteNotes时,它根本不使用setter。我在控制器的这一行后面放了一个断点:

var jobsite = _jobsiteRepository.Jobsites.FirstOrDefault(x => x.Id == id);

并且所有注释都会填充到列表中,但它永远不会出现在设置器中。

2 个答案:

答案 0 :(得分:0)

在JobSite类中进行排序:

   public Jobsite(){
       if(this.JobSiteNotes.Any())
            the.JobSiteNotes.OrderBy(...);
   }

实际上,我认为这会起作用甚至更简单

<!-- html -->
<select id="car">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>


<script>
   // Javascript
   $(document).on('change','#car',function(){
       selectedCar = $(this).val();
       alert(selectedCar);
   });
</script>

答案 1 :(得分:-1)

您应该从已经JobSite获取的对象中获取JobsiteNotes。

private List<JobsiteNote> _jobsiteNotes = null;
public List<JobsiteNote> JobsiteNotes 
{ 
    get
    {
         if (_jobsiteNotes == null)
          {
            _jobsiteNotes = this.Jobsite.JobsiteNotes.OrderByDescending(x => x.CreatedOn).ToList();
          }

          return _jobsiteNotes;
    }
}

然后在您的视图中,您将使用此作为:

<div>
    @foreach (var note in Model.JobsiteNotes)
    {
        @Html.Partial("Note", note)
    }
</div>