EF – 插入的HasQueryFilter等效功能

huangapple go评论68阅读模式
英文:

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&lt;Comment&gt;(entity =&gt;
                {
        
                    entity.HasQueryFilter(c=&gt;c.WebsiteId == this.website_id)
                    // ...
               }
        
          modelBuilder.Entity&lt;Post&gt;(entity =&gt;
                {
        
                    entity.HasQueryFilter(p=&gt;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[&quot;X-WebsiteId&quot;].ToString();
}


// Repository
class MyRepository
{
    private readonly IWebsiteIdAccessor accessor;

    public MyRepository(IWebsiteIdAccessor accessor)
       =&gt; this.accessor = accessor;

    public void addComment(Comment comment){
        comment.WebsiteId = this.accessor.WebsiteId;
        this.Comments.Add(comment);
    }
 }

huangapple
  • 本文由 发表于 2023年5月22日 18:05:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定