如何使网格操作与EF中的自定义属性一起工作

本文关键字:自定义属性 一起 工作 EF 何使 网格 操作 | 更新日期: 2023-09-27 18:10:38

ASP.NET MVC 5网站,我有一个GridView使用devexpress组件绑定使用LINQ方法。

EF生成了一个局部类来映射我用来在gridview中显示的表。在这个由EF生成的部分类中,我有一个ID_Status属性,它在其他表中有相应的描述。我做了另一个部分类来处理这个自定义属性,它工作正常,除了当我试图做一个"排序"操作点击这个列的标题。

EF生成的部分类。

  [Table("Test")]
  public partial class Test
  {
    [Key]
    public long ID_Test { get; set; }
    public long ID_TestStatus { get; set; }
    //other properties
  }

我的自定义部分类:

public partial class Test
{
    private static readonly TestRepository _testRepository;
    static TestRepository()
    {
        _testRepository= new TestRepository();
    }
    public string StatusDescription
    {
        get { return _testRepository.GetStatusDescriptionById(ID_TestStatus); }
    }
}

当我尝试使用另一列Sort时,它工作得很好,但是当我尝试使用自定义属性列Sort时,所有网格单元格值都为空,没有任何值。

任何建议吗?

如何使网格操作与EF中的自定义属性一起工作

将数据访问代码放在实体内部并不是一个好主意。一个原因是它使得编写单元测试变得非常困难。另一个原因是,它很可能产生n + 1反模式。在您的例子中,它做了:一个(1)查询来获取Test s,然后每个Test (n)向数据库发送一个单独的查询来获取其StatusDescription

您实现它的方式也引起了一些质疑,因为

  1. _testRepository是静态的,这意味着在应用程序的整个生命周期中可能存在一些上下文实例——除非GetStatusDescriptionById为每个调用创建一个新的上下文,但这也不是一个好主意。
  2. 每次访问该属性时都会调用GetStatusDescriptionById。在web应用程序中,这可能不是一个大问题,因为对象每次被请求时都是新创建的,但在其他环境中,这可能是非常低效的。

一个更好的方法是获取包含StatusTests:

context.Tests.Include(t => t.TestStatus)

并有一个未映射的属性,如

public string StatusDescription
{
    get { return TestStatus== null ? string.Empty : TestStatus.Description; }
}

更好的(在我看来)是不直接显示Test对象,而是显示TestDto对象,如

public class TestDto
{
    public string StatusDescription { get; set; }
    //other properties that match Test's properties
}

并使用AutoMapper之类的工具将Test s集合映射到TestDto s。如果Test有一个属性Status, TestStatus有一个属性Description, AutoMapper将会自动将其平铺成StatusDescription

这个StatusDescription属性和Dto方法都只设置一次Test(Dto)对象的状态。我不认为任何网格组件可以干扰它