简体   繁体   English

获取EntityFramework的拦截中的实体类型

[英]Get Entity Type in Interception for EntityFramework

I got some problems with interception in Entity-Framework. 我在实体框架截取中遇到了一些问题。 In my scenaryo I want to modify the select sql statemant before it is executed by the sql server. 在我的场景中,我想在选择sql statemant由sql服务器执行之前对其进行修改。 I can see the command when i use interception but is there an easy way to get the entitytype for which this script was generated? 使用拦截时可以看到命令,但是是否有一种简单的方法来获取为此脚本生成的实体类型? I cant find any information about the destination Entity within the interception methods. 我在拦截方法中找不到有关目标实体的任何信息。

I created a very simple adaption from the main project. 我从主项目创建了一个非常简单的改编。

The Entitys: 实体:

[Table("Empty", Schema = "Base")]
public class EmptyBase
{
    [Key]
    [Column("ID", Order = 0)]
    public Guid ID { get; set; }
}

[Table("SoftDele", Schema ="Base")]
public class SoftDeleteBase : EmptyBase
{
    [Column("IsDeleted")]
    public bool IsDeleted { get; set; }

    [Column("IsActive")]
    public bool IsActive { get; set; }
}

[Table("ToolTip", Schema = "Base")]
public class ToolTipBase : SoftDeleteBase
{
    [Column("ToolTip")]
    public string ToolTip { get; set; }
}

[Table("Test1", Schema = "Data")]
public class Test1 : ToolTipBase
{
    [Column("Test1Content")]
    public string Test1Content { get; set; }
}

[Table("Test2", Schema = "Data")]
public class Test2 : SoftDeleteBase
{
    [Column("Test2Content")]
    public string Test2Content { get; set; }
}

DbContext and Interceptors: DbContext和拦截器:

    public class DatabaseCTX : DbContext
    {
     public DatabaseCTX() : base(@"Data Source=localhost;Initial Catalog = SQL_Interception; Integrated Security = True")
    {
        //Database.SetInitializer(new DropCreateDatabaseAlways<DatabaseCTX>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Models.EmptyBase> EmptyBases { get; set; }
    public DbSet<Models.SoftDeleteBase> SoftDeleteBases { get; set; }
    public DbSet<Models.Test1> Test1s { get; set; }
    public DbSet<Models.Test2> Test2s { get; set; }
    public DbSet<Models.ToolTipBase> ToolTipBases { get; set; }
}

public class EFInterception : DbConfiguration
{
    public EFInterception()
    {
        this.AddInterceptor(new EFCommandInterceptor());
        this.AddInterceptor(new EFCommandTreeInterceptor());
    }
}

public class EFCommandTreeInterceptor : IDbCommandTreeInterceptor
{
    public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
    {
        //throw new NotImplementedException();
    }
}

public class EFCommandInterceptor : IDbCommandInterceptor
{
    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
    {
        //throw new NotImplementedException();
    }

    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        //throw new NotImplementedException();
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        //throw new NotImplementedException();
    }

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        //throw new NotImplementedException();
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        //throw new NotImplementedException();
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        //throw new NotImplementedException();
    }
}

And at least a small codebehind from my test-app window: 在我的测试应用程序窗口中至少有一个小代码:

public partial class MainWindow : Window
{        
    Controls.DatabaseCTX databaseCTX;
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        databaseCTX = new Controls.DatabaseCTX();
        //MessageBox.Show(typeof(EF_Interception.Controls.)
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        if(databaseCTX == null)
            databaseCTX = new Controls.DatabaseCTX();
        databaseCTX.Test1s.Add(new Models.Test1() { ID = Guid.NewGuid(), IsActive = true, Test1Content = "asgsewarasfd asdgasdfgasdf asdfg asdfds", ToolTip = "Nope" });
        databaseCTX.Test2s.Add(new Models.Test2() { ID = Guid.NewGuid(), IsActive = true, Test2Content = "asgsewarasfd asdgasdfgasdf asdfg asdfds"});
        databaseCTX.SaveChanges();
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        if (databaseCTX == null)
            databaseCTX = new Controls.DatabaseCTX();
        var a = databaseCTX.Test1s.ToList();
        var b = databaseCTX.Test2s.ToList();
        MessageBox.Show(a.Count.ToString() + "_" + b.Count.ToString());
    }

    private void Button_Click_3(object sender, RoutedEventArgs e)
    {
        if (databaseCTX == null)
            databaseCTX = new Controls.DatabaseCTX();
        var c = databaseCTX.SoftDeleteBases.ToList();
        MessageBox.Show(c.Count.ToString());
    }

The problem is that the generated select script in Button_Click_3- Method also contains all fields from all child tables (test1, test2) In this small example everything works fine but when I use this type of concept in a Big database with 60-70 Tables the generated Select script for the base table is to complex to perform on the sql-server. 问题在于Button_Click_3-方法中生成的选择脚本还包含所有子表(test1,test2)中的所有字段。在这个小示例中,一切正常,但是当我在具有60-70个表的Big数据库中使用这种类型的概念时,基表生成的Select脚本要在sql-server上执行很复杂。 In normal cases this is no problem because I work with the child entitys (test1, test2) directly but it cames to a problem when I try to change the "IsDeleted", "IsActive" or "ToolTip" property of the entity. 在正常情况下,这是没有问题的,因为我直接使用子实体(test1,test2),但是当我尝试更改实体的“ IsDeleted”,“ IsActive”或“ ToolTip”属性时出现问题。

If you want to make changes before saving the dbcontext, you can use the SaveChanges method. 如果要在保存dbcontext之前进行更改,则可以使用SaveChanges方法。

https://exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/ https://exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM