我有一个接口IBasicData
,用于为用户信息(继承代码)实现IVeryBasicData
:
public interface IBasicData:IVeryBasicData
{
byte[] Password { get; set; }
string Email { get; set; }
}
public interface IVeryBasicData:IUser
{
string Name { get; set; }
string UserId { get; set; }
string Description { get; set; }
string Url { get; set; }
}
public interface IUser
{
DateTime CreationTime { get; set; }
string PartitionKey { get; set; }
string RowKey { get; set; }
}
然后我有一个来自UsersDataSource的方法GetUsers
返回IQueryable<IBasicData>
,我希望能够将这个IQueryable用作View的模型。但是当我尝试这样做时会出现异常:例如,在@Hml.DisplayNameFor(model => model.UserId)
中调用它们时无法找到属性。
所以,我已经找到了这个解决方案:
foreach (var user in usersDataSource.GetUsers())
{
var addUser = new UserViewModel()
{
CreationTime = user.CreationTime,
Description = user.Description,
Email = user.Email,
Name = user.Name,
PartitionKey = user.PartitionKey,
Password = user.Password,
RowKey = user.RowKey,
Url = user.Url,
UserId = user.UserId
};
usersViewModel.Add(addUser);
}
return View(usersViewModel);
UserViewModel是一个实现IBasicData
的类。这可行,但对我来说似乎相当丑陋。 是否有更好的方法可以将IQuaryable<IBasicData>
用作View模型?
答案 0 :(得分:1)
更新您的视图,首先在模型声明中获取IEnumerable。
查看强>
@model IEnumerable<IBasicData>
@{foreach(var user in Model){
//I don't know how you are wanting to render out the data...example only
@user.Email<br/>
@user.Name
}}
然后,在您的控制器中,您应该能够执行以下操作:
var modelData = usersDataSource.GetUsers().Select(user=>new UserViewModel{
CreationTime = user.CreationTime,
Description = user.Description,
Email = user.Email,
Name = user.Name,
PartitionKey = user.PartitionKey,
Password = user.Password,
RowKey = user.RowKey,
Url = user.Url,
UserId = user.UserId
}).ToList();
return View(modelData );
调用.ToList()会使查询立即执行并在转到View之前检索数据。
答案 1 :(得分:0)
您确定不会抛出异常,因为在IBasicData接口的对象上运行的模型绑定器只知道密码和电子邮件属性 - 模型绑定器可能使用反射并且可能没有获取基本接口吗?
引自This article on MSDN Magazine,强调我的
例如,即使Microsoft .NET Framework提供 对面向对象原则的出色支持 DefaultModelBinder提供不支持绑定到抽象基础 类和接口。
老实说,我建议您让ViewModel类显式实现所有3个接口,然后将实际EF实体的投影保持在此类的实例中(即usersDataSource.Select(u =&gt; new UserViewModel { ...});然后使用@model IEnumerable
绑定视图接口继承听起来不像这里的正确方法;我不担心你的投影代码,这很正常,请记住它在你的EF层和你的表层(View)之间提供了一个很好的分离。
我同意Tommy虽然在IEnumerable上;一旦你离开你的EF层,IEnumerable就是你的数据,以便实现数据并尽快关闭数据库连接。