How to intercept and modify SQL query in Linq to SQL

前端 未结 4 1277
礼貌的吻别
礼貌的吻别 2021-02-04 15:04

I was wondering if there is any way to intercept and modify the sql generated from linq to Sql before the query is sent off?

Basically, we have a record security layer,

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-04 15:23

    Ok, first to directly answer your question (but read on for words of caution ;)), there is a way, albeit a finicky one, to do what you want.

    // IQueryable L2S query definition, db is DataContext (AdventureWorks)
    var cs = from c in db.Customers 
             select c;
    // extract command and append your stuff
    DbCommand dbc = db.GetCommand(cs);
    dbc.CommandText += " WHERE MiddleName = 'M.'";
    // modify command and execute letting data context map it to IEnumerable
    var result = db.ExecuteQuery(dbc.CommandText, new object[] { });
    

    Now, the caveats.

    1. You have to know which query is generated so you would know how to modify it, this prolongs development.
    2. It falls out of L2S framework and thus creates a possible gaping hole for sustainable development, if anyone modifies a Linq it will hurt.
    3. If your Linq causes parameters (has a where or other extension causing a WHERE section to appear with constants) it complicates things, you'll have to extract and pass those parameters to ExecuteQuery

    All in all, possible but very troublesome. That being said you should consider using .Where() extension as Yaakov suggested. If you want to centrally controll security on object level using this approach you can create an extension to handle it for you

    static class MySecurityExtensions
    {
        public static IQueryable ApplySecurity(this IQueryable source)
        {
            return source.Where(x => x.MiddleName == "M.");
        }
    } 
    
    //...
    // now apply it to any Customer query
    var cs = (from c in db.Customers select c).ApplySecurity();
    

    so if you modify ApplySecurity it will automatically be applied to all linq queries on Customer object.

提交回复
热议问题