1

我正在寻找一种从对象上下文中收集所有对象的好方法和舒适的方法——包括添加和修改的对象。我现在介绍有关 ObjectStateManager 的内容,并且您可以获取它们的对象。但我的问题是,如果使用 linq 查询对象上下文,我必须对修改和添加的对象执行相同的查询并将它们合并在一起。这不是很舒服,总是几行代码。有没有办法很好地包装这个?

我试过这样的事情:

new QueryWrapper<User>(ctx.Users).Where(u => u.Name.StartsWith("A"));

然后我尝试实现我自己的 IQueryable 和我自己的 IQueryProvider 来包装这些东西并获取执行的表达式树。然后我的想法是采用这个表达式树,让它在实体框架和内存集合中运行,我在其中得到修改和添加的对象。我走了很远,我们开始:

public class InMemoryQuery<T> : IQueryable<T> 
{

    private readonly IQueryable<T> _queryable;

    public InMemoryQuery(IQueryable<T> queryable)
    {
        _queryable = queryable;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return this._queryable.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public Expression Expression
    {
        get { return this._queryable.Expression; }
    }

    public Type ElementType
    {
        get { return typeof(T); }
    }

    public IQueryProvider Provider
    {
        get
        {
            return new InMemoryQueryProvider(this._queryable.Provider);
        }
    }
}

这是我的查询提供者

public class InMemoryQueryProvider : IQueryProvider
    {

    private readonly IQueryProvider _innerprovider;

    public InMemoryQueryProvider(IQueryProvider innerprovider)
    {
        _innerprovider = innerprovider;
    }

    public IQueryable CreateQuery(Expression expression)
    {
        throw new System.NotImplementedException();
    }

    public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
    {
        return new InMemoryQuery<TElement>(this._innerprovider.CreateQuery<TElement>(expression));
    }

    public object Execute(Expression expression)
    {
        throw new System.NotImplementedException();
    }

    public TResult Execute<TResult>(Expression expression)
    {
        throw new NotImplementedException();
    }
}

到目前为止,这有效,我能够获得应该在 InMemoryQuery.GetEnumerator 方法中执行的表达式树。伟大的!我的问题是该查询也包含实体框架基本表达式,例如:

Convert(value(ObjectSet`1[EFQueryProviderTest.tbl_Contact]))
    .MergeAs(AppendOnly).Where(n => n.Name.StartsWith("A"))

但我只需要 .Where(...) 上的部分。你懂我的意思吗?然后我想尝试对从对象状态管理器传递的对象执行这部分查询。

你怎么看?这可能吗?你能帮我实现这个目标吗?还是我走错了方向?有没有更好的办法?

4

0 回答 0