英文:
EF - HasQueryFilter equivalent for insertion
问题
我正在处理一个具有相同数据库和每个网站相同架构的多网站应用程序。我使用以下方法来隔离每个实体的查询:
public partial class WebsiteContext : DbContext
{
public WebsiteContext(int website_id)
{
this.website_id = website_id;
}
modelBuilder.Entity<Comment>(entity =>
{
entity.HasQueryFilter(c => c.WebsiteId == this.website_id);
// ...
});
modelBuilder.Entity<Post>(entity =>
{
entity.HasQueryFilter(p => p.WebsiteId == this.website_id);
// ...
});
// 其他实体...
}
但是一些像“Add”这样的方法并没有被隔离。因此,当我调用它时,它会抛出异常,因为需要WebsiteId。我如何确保所有查询,包括插入,都具有Website_id的默认值?
编辑:
大家都在谈论如何过滤更新/选择。
多亏了EF的HasQueryFilter,这已经完成了。
我想要的是一个安全的DbContext,它无法添加任何具有除构造函数参数website_id之外的WebsiteID的对象/行。
我以前向上下文添加了这些方法:
public void addComment(Comment comment)
{
comment.WebsiteId = this.website_id;
this.Comments.Add(comment);
}
public void addPost(Post post)
{
post.WebsiteId = this.website_id;
this.Posts.Add(post);
}
// 其他方法...
那么让我用另一种方式提问我的问题:
如何使“Add”和其他插入方法无效或私有/受保护?
@Panagiotis Kanavos
我知道我能做什么,我只是想要一些隔离。
我希望我的上下文是纯洁的,所以如果我做错了什么,它不会受到影响。
英文:
I'm working on a multi website app with same database and same schema for every website.
I use the following to isolate queries for every entity:
public partial class WebsiteContext : DbContext
{
public WebsiteContext(int website_id)
{
this.website_id = website_id;
}
modelBuilder.Entity<Comment>(entity =>
{
entity.HasQueryFilter(c=>c.WebsiteId == this.website_id)
// ...
}
modelBuilder.Entity<Post>(entity =>
{
entity.HasQueryFilter(p=>p.WebsiteId == this.website_id)
// ...
}
// other entities ...
}
But some methods like "Add" are not isolated .So when I call it it throws exception because WebsiteId is needed.
How can I make sure all of my queries including insertions have default value for Website_id
Edit:
Everyone is talking about how to filter update/select.
Thanks to EF's HasQueryFilter it's done.
What I want is a safe DbCotentxt which is not able to add any object/row with WebsiteID other than website_id (the constructor argument)
I previously added this methods to the context:
public void addComment(Comment comment){
comment.WebsiteId = this.website_id;
this.Comments.Add(comment);
}
public void addPost(Post post)
{
post.WebsiteId = this.website_id;
this.Posts.Add(post);
}
// the rest ...
So let me ask my question other way:
How can I make "Add" and other insertion methods disable or private/protected ?
@Panagiotis Kanavos
I know what I can do, I just want to have some isolation.
I want my context to be innocent so if I do something wrong he doesn't.
答案1
得分: 1
使用一个访问器在中间件中捕获网站ID,然后在您的存储库中使用它插入到域中。
public interface IWebSiteIdAccessor
{
string WebsiteId { get; set; }
}
// 中间件
public async Task Invoke(HttpContext context, IWebSiteIdAccessor accessor)
{
// 从头部或类似位置获取网站ID
accessor.WebsiteId = context.Headers["X-WebsiteId"].ToString();
}
// 存储库
class MyRepository
{
private readonly IWebsiteIdAccessor accessor;
public MyRepository(IWebsiteIdAccessor accessor)
=> this.accessor = accessor;
public void addComment(Comment comment)
{
comment.WebsiteId = this.accessor.WebsiteId;
this.Comments.Add(comment);
}
}
英文:
Use an accessor to capture the website_id during middleware, and then in your repository, use it to insert into the domains.
public interface IWebSiteIdAccessor
{
string WebsiteId {get;set;}
}
// Middleware
public async Task Invoke(HttpContext context, IWebSiteIdAccessor accessor)
{
// Get the website id from a header or similar
accessor.WebsiteId = context.Headers["X-WebsiteId"].ToString();
}
// Repository
class MyRepository
{
private readonly IWebsiteIdAccessor accessor;
public MyRepository(IWebsiteIdAccessor accessor)
=> this.accessor = accessor;
public void addComment(Comment comment){
comment.WebsiteId = this.accessor.WebsiteId;
this.Comments.Add(comment);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论