我正在使用带有Web API的breeze。我没有很好地掌握如何“过滤列”或如何不将公开表和整个表暴露给我的Web API。我使用实体框架作为我的来源,John Papa在这里解决了我的两个问题:http://www.johnpapa.net/spajs04/#comment-113761并且确认是Ward Bell的一个很好的解决方案。有人可以告诉我如何使用实体框架创建一个可在我的webapi中查询的部分或投影,并且可以使用breeze吗?
这是我在webapi中的当前功能
[HttpGet]
public IQueryable<Contact> GetContacts()
{
return _contextProvider.Context.Contact;
}
这是我目前的课程:
public class Contact
{
[Key]
public Guid ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string NickName { get; set; }
public string JobTitle { get; set; }
public DateTime BirthDate { get; set; }
public bool Gender { get; set; }
public string SSN { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUpdated { get; set; }
public virtual ICollection<Address> Address { get; set; }
}
我希望有一个可查询的webapi函数,它是我当前的类 WITHOUT SSN字段。一个“数据库优先”实体的解决方案,不涉及更改我的数据库或添加“视图”将是伟大的。
答案 0 :(得分:6)
当您尝试减少有效负载时,客户端投影很好。当您必须确保某些数据(例如SSN)真正安全地从客户端隐藏时,您需要服务器端。
@james建议 - 使用[NonSerialized]
(或JSON.NET的[JsonIgnore]
属性) - 当SSN 从不时,这是一种简单有效的方法去客户端。
如果在授权的情况下客户端可以看到SSN(例如,用户查看自己的SSN或有权查看SSN的人权),则太不灵活了。 JSON.NET IContractResolver为您提供了极大的灵活性,可以根据授权规则动态决定哪些属性可以跨越服务边界。
有些人可能会考虑使用序列化程序解决这个问题太多了。他们可能会对您展示的服务器端投影表示满意,@ chris_dotnet。顺便说一下,从投影中返回IQueryable
仍然有意义,这样客户端就可以通过过滤查询来减少网络负载。
其他人更愿意定义DTO(ContactDTO
)并通过网络序列化。
[HttpGet] public IQueryable GetContacts() { return _contextProvider.Context.Contacts .Select(p => new ContactDto { FirstName = p.FirstName, ID = p.ID, LastName = p.LastName }); }
此IQueryable
比投影版本更强大,因为过滤可以在数据层而不是服务器层上进行。
在客户端,您可以定义ContactDto
类型的元数据,也可以使用JsonResultsAdapter
将ContactDto
数据映射到Contact
Breeze实体。
使用JsonResultsAdapter
预先假定您确实需要Contact
类型 - 在服务器上的业务模型中形成的类型 - 在客户端上已知。
您可能不希望从服务中公开服务器端Contact
形状。许多人对此非常强烈。如果您是其中一个人,那么最好定义一个代表实体的“DTO模型”,以便在客户端上看到它们。这意味着学习为DTO模型创建元数据,并在服务器上编写映射逻辑,以便在DTO和业务模型之间移动。
您可以看到所有这些都可以成为一个大话题。这是我将在Breeze文档中尽快讨论的内容。考虑这个答案,尝试一下即将发生的事情。外卖是......你可以选择隐藏用户不应该看到的数据。
答案 1 :(得分:2)
感谢John提供此信息,我看了一下,这对客户端过滤很有帮助。我发现我可以从客户端和/或服务器端执行此操作。
客户端微风:
var query = EntityQuery.from("Customers")
.select("ID, FirstName, LastName");
服务器端:
[HttpGet]
public IQueryable<Contact> GetContacts()
{
var contactList = _contextProvider.Context.Contacts
.ToList()
.Select(p =>
new Contact
{
FirstName = p.FirstName,
ID = p.ID,
LastName = p.LastName
})
.AsQueryable(); // actually IQueryable is not useful after "ToList()"
return contactList ;
}
答案 2 :(得分:1)
克里斯 - 在演讲中有一个例子,演讲者和会话部分。我返回那些我没有返回描述字段(用于会话)或生物字段(用于发言者)的投影。检查出来并使用相同的样式不显示您的Employee类的SSN字段
答案 3 :(得分:1)
您无法将属性标记为[NonSerialized]
[NonSerialized]
public string SSN { get; set; }
答案 4 :(得分:1)
我刚刚找到了另一种根据标准忽略列的解决方案。只需添加属于感兴趣模型的部分类(我的模型生成)并使用ShouldSerialize%PropertyName%
:
namespace ProvSys.Models
{
partial class tblEmployees
{
public static bool ShouldSerializeResetPassword()
{
// Only hand over ResetPassword Field for admin role
return (ProvSysRepository.IsAdmin);
}
}
}
在此示例中,ResetPassword
表的tblEmployees
属性仅在用户处于管理员角色时才会传输。