在ASP.NET MVC 5
网站中,我有一个使用LINQ方法使用devexpress组件绑定的GridView。
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
}
My Custom partial class:
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
使用自定义属性列时,所有网格单元格值都为空,没有任何值。
有什么建议吗?
答案 0 :(得分:1)
在实体内部拥有数据访问代码并不是一个好主意。一个原因是它使编写单元测试变得非常困难。另一个原因是它很可能产生n + 1反模式。在您的情况下,它执行:one(1)查询以获取Test
,然后每个Test
(n)向数据库发送单独的查询以获取其StatusDescription
。
你实施它的方式也引起了一些人的注意,因为
_testRepository
是静态的,可能会有一些上下文实例存在于应用程序的整个生命周期中 - 除非GetStatusDescriptionById
为每个调用创建一个新的上下文,但这不是一个好主意。GetStatusDescriptionById
调用。在Web应用程序中,这可能不是一个大问题,因为对象是每次请求时都是新创建的,但在其他环境中这可能是非常低效的。更好的方法是获取包含Tests
的{{1}}:
Status
并有一个未映射的属性,如
context.Tests.Include(t => t.TestStatus)
更好(我认为)不是直接显示public string StatusDescription
{
get { return TestStatus== null ? string.Empty : TestStatus.Description; }
}
个对象,而是Test
个对象,如
TestDto
并使用AutoMapper等工具将public class TestDto
{
public string StatusDescription { get; set; }
//other properties that match Test's properties
}
s的集合映射到Test
s。如果TestDto
具有属性Test
且Status
具有属性TestStatus
,则AutoMapper将能够自动将其展平为Description
。
此StatusDescription
属性和Dto appraoch都设置了StatusDescription
对象的状态一次。我不认为任何网格组件都可以搞乱它。