См. SQL From EntityFramework с коллекционными запросами - PullRequest
2 голосов
/ 27 августа 2010

У меня нет «полной» версии MS SQL (SQL Express 2008), поэтому у меня нет инструмента профилирования.

Я хочу увидеть SQL, сгенерированный моим кодом Entity Framework, но все примеры, которые я нахожу, используют

var x = from u in table
        select u;

тип синтаксиса; Но большинство моих запросов больше похоже на ...

var x = context.Users.Single(n => n.Name == "Steven");

тип синтаксиса. Что я могу сделать, чтобы увидеть сгенерированный SQL из этого способа кодирования? Есть идеи?

Ответы [ 2 ]

3 голосов
/ 27 августа 2010

проверьте эту ссылку ... у нее есть поставщик трассировки для EF4.

Я попытаюсь привести пример, основанный на том, как я использую это в модульном тесте.

Шаг 1: Зарегистрируйте провайдера

Существует несколько способов настройки провайдера. Для моих модульных тестов я настроил провайдера в коде, вызвав статический метод RegisterProvider ();

[AssemblyInitialize()]
public static void AssemblyInit(TestContext context) {
    EFTracingProviderConfiguration.RegisterProvider();
}

Шаг 2. Создайте подкласс своей модели сущности для предоставления расширений трассировки

public partial class ExtendedNorthwindEntities : NorthwindEntities {
    private TextWriter logOutput;

    public ExtendedNorthwindEntities(string connectionString)
        : base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
                connectionString,
                "EFTracingProvider")) {
    }

    #region Tracing Extensions

    private EFTracingConnection TracingConnection {
        get { return this.UnwrapConnection<EFTracingConnection>(); }
    }

    public event EventHandler<CommandExecutionEventArgs> CommandExecuting {
        add { this.TracingConnection.CommandExecuting += value; }
        remove { this.TracingConnection.CommandExecuting -= value; }
    }

    public event EventHandler<CommandExecutionEventArgs> CommandFinished {
        add { this.TracingConnection.CommandFinished += value; }
        remove { this.TracingConnection.CommandFinished -= value; }
    }

    public event EventHandler<CommandExecutionEventArgs> CommandFailed {
        add { this.TracingConnection.CommandFailed += value; }
        remove { this.TracingConnection.CommandFailed -= value; }
    }

    private void AppendToLog(object sender, CommandExecutionEventArgs e) {
        if (this.logOutput != null) {
            this.logOutput.WriteLine(e.ToTraceString().TrimEnd());
            this.logOutput.WriteLine();
        }
    }

    public TextWriter Log {
        get { return this.logOutput; }
        set {
            if ((this.logOutput != null) != (value != null)) {
                if (value == null) {
                    CommandExecuting -= AppendToLog;
                }
                else {
                    CommandExecuting += AppendToLog;
                }
            }

            this.logOutput = value;
        }
    }

    #endregion
}

Шаг 3: Присоединить к свойству Log

var context = new ExtendedNorthwindEntities("name=\"NorthwindEntities\"");

context.Log = System.Console.Out;
1 голос
/ 27 августа 2010

Express Edition поддерживает расширенные события? Если это так, это будет захватывать оператор и sp завершенные события аналогично Profiler.

Редактировать: Я изменил его, чтобы использовать цель памяти, а не цель файла. В идеале раскомментируйте разделы WHERE и замените их соответствующим именем пользователя, чтобы захватить только интересующие вас события, или вы можете фильтровать по spid, например, с помощью WHERE (([sqlserver].[session_id]=(56))).

IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='test_trace')
    DROP EVENT SESSION [test_trace] ON SERVER;
CREATE EVENT SESSION [test_trace]
ON SERVER
ADD EVENT sqlserver.sp_statement_completed(
     ACTION (package0.callstack, sqlserver.session_id, sqlserver.sql_text)
    -- WHERE (([sqlserver].[username]='Domain\Username'))
    ),
ADD EVENT sqlserver.sql_statement_completed(
     ACTION (package0.callstack, sqlserver.session_id, sqlserver.sql_text)
     --WHERE (([sqlserver].[username]='Domain\Username'))
     )
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY = 4096KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, 
MAX_DISPATCH_LATENCY = 1 SECONDS, MAX_EVENT_SIZE = 0KB, 
MEMORY_PARTITION_MODE = NONE, TRACK_CAUSALITY = OFF, STARTUP_STATE = OFF)

ALTER EVENT SESSION [test_trace] ON SERVER STATE = START

И для просмотра результатов (Запрос сгенерирован с использованием Генератор кода XE Адама Мачаника )

DECLARE 
    @session_name VARCHAR(200) = 'test_trace'

SELECT 
    pivoted_data.* 
FROM 
( 
 SELECT MIN(event_name) AS event_name,
     MIN(event_timestamp) AS event_timestamp,
     unique_event_id,
     CONVERT ( BIGINT, MIN (
         CASE
             WHEN d_name = 'cpu'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [cpu],
     CONVERT ( BIGINT, MIN (
         CASE
             WHEN d_name = 'duration'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [duration],
     CONVERT ( BIGINT, MIN (
         CASE
             WHEN d_name = 'object_id'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [object_id],
     CONVERT ( INT, MIN (
         CASE
             WHEN d_name = 'object_type'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [object_type],
     CONVERT ( DECIMAL(28,0), MIN (
         CASE
             WHEN d_name = 'reads'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [reads],
     CONVERT ( VARCHAR(MAX), MIN (
         CASE
             WHEN d_name = 'session_id'
             AND d_package IS NOT NULL
             THEN d_value
         END ) ) AS [session_id],
     CONVERT ( INT, MIN (
         CASE
             WHEN d_name = 'source_database_id'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [source_database_id],
     CAST((SELECT CONVERT ( VARCHAR(MAX), MIN (
         CASE
             WHEN d_name = 'sql_text'
             AND d_package IS NOT NULL
             THEN d_value
         END ) )  AS [processing-instruction(x)] FOR XML PATH('') ) AS XML) AS [sql_text],
     CONVERT ( DECIMAL(28,0), MIN (
         CASE
             WHEN d_name = 'writes'
             AND d_package IS NULL
             THEN d_value
         END ) ) AS [writes]
 FROM
    ( 
        SELECT 
            *, 
            CONVERT(VARCHAR(400), NULL) AS attach_activity_id 
        FROM 
        ( 
            SELECT 
                event.value('(@name)[1]', 'VARCHAR(400)') as event_name, 
                event.value('(@timestamp)[1]', 'DATETIME') as event_timestamp, 
                DENSE_RANK() OVER (ORDER BY event) AS unique_event_id, 
                n.value('(@name)[1]', 'VARCHAR(400)') AS d_name, 
                n.value('(@package)[1]', 'VARCHAR(400)') AS d_package, 
                n.value('((value)[1]/text())[1]', 'VARCHAR(MAX)') AS d_value, 
                n.value('((text)[1]/text())[1]', 'VARCHAR(MAX)') AS d_text 
            FROM 
            ( 
                SELECT 
                    ( 
                        SELECT 
                            CONVERT(xml, target_data) 
                        FROM sys.dm_xe_session_targets st 
                        JOIN sys.dm_xe_sessions s ON 
                            s.address = st.event_session_address 
                        WHERE 
                            s.name = @session_name 
                            AND st.target_name = 'ring_buffer' 
                    ) AS [x] 
                FOR XML PATH(''), TYPE 
            ) AS the_xml(x) 
            CROSS APPLY x.nodes('//event') e (event) 
            CROSS APPLY event.nodes('*') AS q (n) 
        ) AS data_data 
    ) AS activity_data 
    GROUP BY 
        unique_event_id 
) AS pivoted_data; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...