Получить тип сущности в перехвате для EntityFramework - PullRequest
0 голосов
/ 02 октября 2018

У меня возникли проблемы с перехватом в Entity-Framework.В моем сценарии я хочу изменить выбранный sql statemant до того, как он будет выполнен сервером sql.Я вижу команду, когда использую перехват, но есть ли простой способ получить тип сущности, для которого был сгенерирован этот скрипт?Я не могу найти какую-либо информацию об объекте назначения в методах перехвата.

Я создал очень простую адаптацию из основного проекта.

Объекты:

[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и перехватчики:

    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();
    }
}

И хотя бы небольшой код из окна моего тестового приложения:

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());
    }

Проблема в том, что сгенерированный скрипт выбора в Button_Click_3- Method также содержит все поляиз всех дочерних таблиц (test1, test2) В этом небольшом примере все работает нормально, но когда я использую этот тип концепции в большой базе данных с 60-70 таблицами, сгенерированный сценарий Select для базовой таблицы сложен для выполнения на sql-сервер.В обычных случаях это не проблема, потому что я работаю с дочерними сущностями (test1, test2) напрямую, но возникает проблема, когда я пытаюсь изменить свойство «IsDeleted», «IsActive» или «ToolTip» сущности.

1 Ответ

0 голосов
/ 02 октября 2018

Если вы хотите внести изменения перед сохранением dbcontext, вы можете использовать метод SaveChanges.

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

...