Entity Framework 4.1: Unable to cast from DbQuery to ObjectQuery

后端 未结 2 1789
日久生厌
日久生厌 2020-12-01 14:39

I have the following code:

public void DeleteAccountsForMonth(int year, int month)
{
    var result = from acm in this._database.AccountsOnMonth
                     


        
相关标签:
2条回答
  • 2020-12-01 15:02

    That is because your _database is derived from DbContext and your AccountsOfMonth is DbSet<>. In such case you cannot use ObjectQuery directly because DbSet<> produces DbQuery<> which is not convertible to ObjectQuery<>.

    You must either use DbQuery<> directly:

    var result = from acm in this._database.AccountsOnMonth
                 where ((acm.Year == year) && (acm.Month == month))
                 select acm.Id;
    var query = (DbQuery<int>)result;
    
    string sql = string.Format(
        "DELETE FROM [AccountsOnMonth] WHERE [AccountsOnMonth].[Id] IN ({0})",
        query.ToString()
    );
    

    Or you must first convert your context to ObjectContext and create ObjectSet<>:

    var objectContext = ((IObjectContextAdapter)_database).ObjectContext;
    var set = objectContext.CreateObjectSet<AccountsOnMonth>();
    var resut = from acm in set
                where ((acm.Year == year) && (acm.Month == month))
                select acm.Id;
    

    The problem with first approach is that DbQuery doesn't offer Parameters collection - just another example of simplification in DbContext API which only makes it harder to use.

    0 讨论(0)
  • 2020-12-01 15:04

    In my case I really needed the parameters and I found this workaround:

    var query = (DbQuery<int>)result;
    
    FieldInfo internalQueryField = query.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_internalQuery")).FirstOrDefault();
    var internalQuery = internalQueryField.GetValue(query);
    FieldInfo objectQueryField = internalQuery.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => f.Name.Equals("_objectQuery")).FirstOrDefault();
    ObjectQuery<int> objectQuery = objectQueryField.GetValue(internalQuery) as ObjectQuery<int>;
    
    foreach (ObjectParameter objectParam in objectQuery.Parameters)
    {
        SqlParameter sqlParam = new SqlParameter(objectParam.Name, objectParam.Value);
        // Etc...
    }
    

    I'm implementing SqlCacheDependency with Entity Framework. :-)

    0 讨论(0)
提交回复
热议问题