Найдите базовые таблицы представлений, используя Linq to Entity для создания совокупных зависимостей - PullRequest
0 голосов
/ 14 ноября 2011

У меня есть функция:

 public static List<T> EntityCache<T>(this System.Linq.IQueryable<T> q, ObjectContext dc, string CacheId)
    {


        try
        {
            List<T> objCache = (List<T>)System.Web.HttpRuntime.Cache.Get(CacheId);

            string connStr = (dc.Connection as System.Data.EntityClient.EntityConnection).StoreConnection.ConnectionString;

            if (objCache == null)
            {
                ObjectQuery<T> productQuery = q as ObjectQuery<T>;

                string sqlCmd = productQuery.ToTraceString();

                using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr))
                {
                    conn.Open();
                    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sqlCmd, conn))
                    {

                        string NotificationTable = q.ElementType.Name;
                        System.Web.Caching.SqlCacheDependency sqldep = new System.Web.Caching.SqlCacheDependency(cmd);
                        cmd.ExecuteNonQuery();
                        objCache = q.ToList();
                        System.Web.HttpRuntime.Cache.Insert(CacheId, objCache, sqldep);
                    }
                }
            }

            return objCache;

        }
        catch (Exception ex)
        {
            throw ex;
        }

    }

q может быть таблицей, представлением или процедурой.

Мне нужно найти базовые таблицы, связанные с представлением или процедурой.

например, если q является объединением таблиц буксировки, я хочу получить имя обеих таблиц и, наконец,

выполнить следующим образом:

Если есть две таблицы, скажите Aи B

Затем мне нужно сделать Aggregate Dependency следующим образом:

  string sqlCmd1 = string.Empty;
                        string sqlCmd2 = string.Empty;

                        using (testEntities ctx1 = new testEntities())
                        {
                            sqlCmd1 = ((System.Data.Objects.ObjectQuery)(from p in ctx1.A select p)).ToTraceString();
                            sqlCmd2 = ((System.Data.Objects.ObjectQuery)(from p in ctx1.B select p)).ToTraceString();
                        }

                        System.Data.SqlClient.SqlCommand cmd1 = new System.Data.SqlClient.SqlCommand(sqlCmd1, conn);
                        System.Data.SqlClient.SqlCommand cmd2 = new System.Data.SqlClient.SqlCommand(sqlCmd2, conn);


 System.Web.Caching.SqlCacheDependency
                       dep1 = new System.Web.Caching.SqlCacheDependency(cmd1),
                       dep2 = new System.Web.Caching.SqlCacheDependency(cmd2);

                        System.Web.Caching.AggregateCacheDependency aggDep = new System.Web.Caching.AggregateCacheDependency();
                        aggDep.Add(dep1, dep2);

                        cmd1.ExecuteNonQuery();
                        cmd2.ExecuteNonQuery();

, тогда запрос, который я хочу выполнить, будет

select * from A;select * from B;

Это я использую для SqlCacheDependency с использованием Linq to Entity.

Хорошо работает для представлений, когда я жестко кодирую базовые таблицы, но теперь я хочу, чтобы код автоматически проверял базовыетаблиц

и выполнять запросы, например

   cmd1.ExecuteNonQuery();
   cmd2.ExecuteNonQuery();

и создавать совокупные зависимости.

Любая помощь приветствуется.

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 ноября 2011

Вы должны использовать инструменты уровня базы данных, чтобы найти, от каких объектов базы данных зависят ваши представления или хранимые процедуры (но это также означает, что вы должны знать их полные имена в базе данных). Например, SQL-сервер предлагает sp_depends системную хранимую процедуру для отслеживания зависимостей. Это может быть довольно сложно, поскольку зависимости могут иметь несколько уровней (процедура может зависеть от представления, представление может зависеть от другого представления и т. Д.).

Имейте в виду, что расширенное отображение EF также позволяет писать SQL напрямую в EDMX, и в этом случае вам придется анализировать ToTraceString, чтобы найти объекты базы данных.

0 голосов
/ 17 ноября 2011

Я нашел решение для проблемы, которую я опубликовал.

Существует запрос, который действителен для SQL Server 2005 года.

Нам нужно передать имя объекта ион вернет нам имя таблиц, от которых зависит

Пример:

Имя представления скажет AllProducts_Active_Inactive

                 ;WITH CTE AS (SELECT   o.name
            ,       o.type_desc 
            ,       p.name
            ,       p.type_desc as B
            ,       p.object_id
            FROM    sys.sql_dependencies d
                    INNER JOIN sys.objects o
                    ON d.object_id = o.object_id
                    INNER JOIN sys.objects p
                    ON d.referenced_major_id = p.object_id

                    where o.name = 'AllProducts_Active_Inactive'

            UNION ALL
            SELECT  o.name
            ,       o.type_desc 
            ,       p.name
            ,       p.type_desc as B
            ,       p.[object_id]
            FROM    sys.sql_dependencies d
                    INNER JOIN CTE o
                    ON d.object_id = o.object_id
                    INNER JOIN sys.objects p
                    ON d.referenced_major_id = p.object_id

                    where o.name = 'AllProducts_Active_Inactive'

                   ) 
            SELECT DISTINCT * FROM [CTE]
            where B = 'USER_TABLE'

Этот пост является измененным ответом на вопрос, который я разместил на сайте:

http://ask.sqlservercentral.com/questions/81318/find-the-underlying-tables-assocaited-with-a-view-or-a-stored-procedure-in-sql-server

Что я изменил, добавлена ​​строка, где B ='USER_TABLE'

Это означает, что возвращаются только те зависимости, которые являются таблицами.

И добавляется секунда в предложение WHERE , чтобы конкретный объект былнайдено.

Спасибо

...