我正在使用EF 4.1,我正在尝试枚举网格的公司列表。我在当前项目中有两个选项:从DbContext(Entities
)中选择所有公司并将它们加载到非匿名类型的对象中(假设为EmpresaGrid
)或将所有公司选择为匿名类型具有相同结构的对象,如Empresa
(我正在选择的实体)。
第一个选项(为此创建一个模型类)需要更多的工作,但最终可以更具可读性。不过,我对此并不确定。第二个选项是我现在正在使用的。
那么,第一个问题:最好只为显示数据或使用匿名类型创建模型类?直接选择是不可能的:SELECT *
太大了,可能会让一切都变慢(我猜)。因此,选择另一种类型会创建仅包含所需字段的自定义查询。
使用第二个选项(匿名类型),我有这个代码(简化版):
public static IEnumerable<object> Grid()
{
Entities db = new Entities();
var empresas = db.Empresas
.Select(e => new
{
Cgc = e.Cgc, // PK
(...)
Address = new
{
AddressLine = e.EnderecoSede.AddressLine,
(...)
}
},
Contato = e.Contato,
(...)
})
.ToList();
return empresas;
}
我正在创建的匿名类型有大约40行代码,所以它有点大,但它重新创建了Empresa
类结构的一部分(因为网格正在等待Empresa
对象) 。无论如何,我的数据格式有问题。例如,我想使用自定义字符串格式格式化Cgc
属性。我有一个公共方法,FormataCgc
。此方法接收一个字符串并使用某些内部条件返回格式。
所以,我的问题是如何做到这一点。例如,我试过这个:
var empresas = db.Empresas
.Select(e => new
{
Cgc = FormataCgc(e.Cgc),
}
但这不起作用,因为FormataCgc无法转换为SQL(我不想转换它)。我也试过这个:
var empresas = db.Empresas
.Select(e => new
{
(...)
}
.ToList();
foreach (var e in empresas) {
e.Cgc = FormataCgc(e.Cgc);
}
但由于匿名类型只有只读属性,所以无法完成。
所以,我的第二个问题是:我该怎么做?我需要在选择数据后更改数据,但使用匿名类型?我做了一些研究,我发现的最好的事情就是:Calling a custom method in LINQ query。在该解决方案中,Ladislav建议从IEnumerable中进行第二次选择,但由于网格不是Empresa
,我不能这样做(我需要更改或添加属性,而不是封装它们)。
我不确定我是否足够清楚,但随时可以提出任何问题。此外,我目前正在使用的网格是Telerik ASP.NET MVC网格,它接收IEnumerable(其中T是一个类)作为模型数据,它们迭代每个对象,发挥其魔力。
答案 0 :(得分:4)
由于您已将其转换为IEnumerable<T>
,因此您可以在客户端中流式传输结果时执行自定义格式设置。做db.Select,然后转换为适当的格式,即:
var empresas = db.Empresas
.Select(e => new
{
(...)
})
.ToList();
foreach (var e in empresas) {
yield return new {
Cgc = FormataCgc(e.Cgc),
// Copy other properties here, as needed...
};
}
话虽这么说,我个人建议制作一个自定义类,而不是返回一个匿名类型。您的转换将是:
foreach (var e in empresas) {
yield return new YourClass(FormataCgc(e.Cgc), ...); // Construct as needed
}
这将显着提高此方法的可用性,因为您将从方法的调用方对属性进行适当的命名访问。
答案 1 :(得分:1)
我认为你的两个问题的解决方案是创建一个模型类。当然,预计会有更多的工作,但从长远来看,它将为您提供更大的灵活性。然后,您的自定义模型类可以为您处理格式。
public class EmpresaGridModel
{
public string Cgc { get; set; }
public string CgcFormatted
{
return FormataCgc(this.Cgc);
}
//properties for the other fields will have to be created as well obviously
}
然后,您的telerik网格可以直接绑定到CgcFormatted属性