作为一个简化的例子,我有用户、产品和客户。允许用户访问某些产品和某些客户。
我使用edmx文件将我的Server映射到我的代码,并使用linq获取数据。典型的查询可能如下所示:
from prod in ctx.Products
join userProduct in ctx.UserProduct
on prod.Id equals userProduct.ProductId
join user in ctx.UserProfile
on userProduct.UserId equals user.Id
where user.UserName == username // <-- username is a method parameter
select new Product
{
Id = prod.Id,
DisplayText = prod.UserFriendlyText
}每次我需要数据库中的数据时,我都必须加入到访问权限表中,以排除用户无法访问的数据。这意味着,如果有人(最终会发生)忘记加入access表,用户就会看到太多。是否有一种方法可以代替包含数据,以便如果我忘记了访问表,就不会显示任何数据?
我还一直在考虑将不同的客户划分到不同的数据库中,因为他们的数据永远不会相互关联,如果我在客户之间泄露数据,这将是一场小小的灾难。用户之间从同一客户泄露产品是不好的,但没有那么关键。
如果重要的话,我是在C# MVC4 CQRS体系结构中,读写端之间最终是一致的。
我检查了堆栈溢出是否有类似的问题,但我只能找到一个未回答的问题:
发布于 2013-11-26 08:29:26
如何使用存储库模式,并迫使您的开发人员使用它来调用数据库?这将促进代码重用,并提高应用程序的可维护性。
因为将从存储库中调用方法,所以可以控制与数据库交互的代码,并强制一致性,这样您就可以确保访问表始终被使用,并按您的意愿使用。
发布于 2013-11-26 11:47:16
我的数据库中也有类似的问题。我的实体中有90%是“依赖组织的”。我的方法使用了一个通用的基本存储库,其方法如下:
public virtual T Find(int id)
{
T e = Context.Set<T>().Find(id);
var od = e as OrganisationDependent;
if (od != null && od.OrganisationID != CurrentOrganisationID)
return null;
if (e == null)
return null;
return e;
}“所有”方法是一个特殊问题。用如何有条件地过滤IQueryable解决
private static readonly PropertyInfo _OrganisationIDProperty = ReflectionAPI.GetProperty<OrganisationDependent, int>(o => o.OrganisationID);
private static Expression<Func<TOrg, bool>> FilterByOrganization<TOrg>(int organizationId)
{
//The FilterByOrganisation method uses the LINQ Expressions API to generate an expression that will filter on organisation id
//This avoids having to cast the set using .AsEnumerable().Cast<OrganisationDependent>().Where(x => x.OrganisationID == CurrentOrganisationID).AsQueryable().Cast<T>();
//https://stackoverflow.com/questions/20052827/how-to-conditionally-filter-iqueryable-by-type-using-generic-repository-pattern
var item = Expression.Parameter(typeof(TOrg), "item");
var propertyValue = Expression.Property(item, _OrganisationIDProperty);
var body = Expression.Equal(propertyValue, Expression.Constant(organizationId));
return Expression.Lambda<Func<TOrg, bool>>(body, item);
}
public virtual IQueryable<T> All
{
get
{
if (typeof(T).IsSubclassOf(typeof(OrganisationDependent)))
return Context.Set<T>().Where(FilterByOrganization<T>(CurrentOrganisationID));
return Context.Set<T>();
}
}这将关闭大多数用户可以访问他人数据的地方。但它不过滤导航属性。因此,我必须向非组织依赖的实体上的所有导航属性添加代码才能做到这一点。
我不想将我的数据分离到不同的数据库中,但是有一天我会发现在不同的模式中创建由组织过滤的视图是否可行--与我的表具有相同的名称和结构,然后根据user.....oh切换模式,我希望为每个新的组织自动创建它们,并使用代码自动迁移它们--首先.
你可以在这里投票给允许对包含扩展方法进行过滤
发布于 2013-12-05 11:29:11
如果您使用的是CQRS风格的体系结构,您可以考虑让每个用户拥有一个或多个视图模型,其中包含他们可以访问的产品/客户。
如果您认为自己必须在CQRS的查询端实现逻辑,这就有力地表明您正在做错误的事情。
https://stackoverflow.com/questions/20210419
复制相似问题