如何使网格操作与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
时,所有网格单元格值都为空,没有任何值。
任何建议吗?
将数据访问代码放在实体内部并不是一个好主意。一个原因是它使得编写单元测试变得非常困难。另一个原因是,它很可能产生n + 1反模式。在您的例子中,它做了:一个(1)查询来获取Test
s,然后每个Test
(n)向数据库发送一个单独的查询来获取其StatusDescription
。
您实现它的方式也引起了一些质疑,因为
-
_testRepository
是静态的,这意味着在应用程序的整个生命周期中可能存在一些上下文实例——除非GetStatusDescriptionById
为每个调用创建一个新的上下文,但这也不是一个好主意。 - 每次访问该属性时都会调用
GetStatusDescriptionById
。在web应用程序中,这可能不是一个大问题,因为对象每次被请求时都是新创建的,但在其他环境中,这可能是非常低效的。
一个更好的方法是获取包含Status
的Tests
:
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)
对象的状态。我不认为任何网格组件可以干扰它