문제

I have a function:

 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 can be a table, view or a procedure.

What i want is to find the underlying tables associated with a view or a procedure.

like if q is a join of tow tables i want to get the name of both the tables and finally

execute like:

If there are tw0 tables say A and B

Then i need to make Aggregate Dependency like:

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

then the query i want to execute is

select * from A; select * from B;

This i am using for SqlCacheDependency using Linq to Entity.

It works well for views when i hardcode the underlying tables but now i want the code automatically check for the underlying tables

and execute nonquery like

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

and make aggregate dependencies.

Any help is appreciated.

Thanks.

도움이 되었습니까?

해결책

You must use database level tools to find which database objects your views or stored procedures depends on (but it also means you must know their full names in the database). For example SQL server offers sp_depends system stored procedure to track dependencies. This can be quite complicated because dependencies can have multiple levels (procedure can be dependent on view, view can be dependent on another view, etc.).

Be aware that advanced EF mapping also allows writing SQL directly to EDMX and in such case you will have to parse ToTraceString to find database objects.

다른 팁

I have found a solution for the problem i have posted.

There is a query that is valid for sql server 2005 onward.

We need to pass the name of the object and it will return us the name of the tables on which it depends

Example:

The name of the View is say 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'

This post is the modified answer of the question i have posted on the website:

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

What i changed is added the line where B = 'USER_TABLE'

Which means only those dependencies are returned who are tables.

And the seconds thing is added a WHERE clause so that a specific object is found.

Thanks

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top