1

我有一个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; }
}

然后我有一个GetUsers来自 UsersDataSource 的方法,它返回一个IQueryable<IBasicData>,我希望能够使用这个 IQueryable 作为视图的模型。@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. 这有效,但对我来说似乎相当难看有没有更好的方法可以将 anIQuaryable<IBasicData>用作 View 模型?

4

2 回答 2

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() 会导致查询立即执行并在转到您的视图之前检索数据。

于 2013-07-15T22:18:27.800 回答
1

您确定没有抛出异常,因为模型绑定器在接口 IBasicData 的对象上运行,只知道密码和电子邮件属性 - 模型绑定器可能使用反射并且可能没有拾取基本接口?

引用MSDN 杂志上的这篇文章,强调我的

例如,尽管 Microsoft .NET Framework 为面向对象的原则提供了出色的支持,但 DefaultModelBinder不支持绑定到抽象基类和接口。

老实说,我建议让您的 ViewModel 类明确实现所有 3 个接口,然后将实际 EF 实体的投影保留到此类的实例中(即 usersDataSource.Select(u=>new UserViewModel{...} ); 然后使用@model IEnumerable 在视图上绑定

接口继承在这里听起来不像是正确的方法。我不会担心您拥有的投影代码,这很正常,请记住它在 EF 层和表示层(视图)之间提供了很好的分离。

尽管在 IEnumerable 上,我确实同意 Tommy 的观点;一旦你离开你的EF层,IEnumerable-ise你的数据马上就可以实现你的数据并尽快关闭数据库连接。

于 2013-07-15T23:43:59.507 回答