English 中文(简体)
如何用临时 Sql 查询进行懒惰装载 : SQL 过滤
原标题:How to do lazy loading with ad hoc sql queries : SQL Filtering

只是想知道它是否有可能在没有遥控器或ORM的情况下进行懒惰的装载。 有些问题我需要这样做,这对ORMs来说是不合适的。 我还需要在方法之间通过查询。 另外,我找不到任何微型金刚石来做到这一点。 有没有办法这样做?

var q = "Select Name from Test1"

现在,我们必须加上一个或者,或者 和,或者在或者其他的东西

此查询将传递到要过滤的不同方法。 是否有方法使用微操作器或 Ad Hoc SQL 查询来做到这一点?

最佳回答

一种方法是将查询表达为某种在模拟对象,您可以进一步添加该对象的表达式。例如,使用由对象结构组成的某些对象结构:

var q = Table("Test1").Select("Name");

您将会通过添加过滤器来进一步完善这一点 :

q = q.Where("ID= 1");

当然,这意味着你正在重新发明"http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx" rel=“nofollow”\\code>IQueryable 。你最好接受LINQ,然后选择一个提供者(LINQ2SQL或LINQ2EF 等)。

另一种办法是保持字符串临时代表方式:

var q = "Select Name from Test1";

如何添加过滤器? 您必须剖析字符串, 并插入条款所在位置 。 这远非微不足道 。 您将很快执行一个完整的 SQL parser (< href='http:// en. wikipedia. org/ wiki/ Lex_ 28 software% 29' rel= “ nofollow” >lex < lex < lex < en. wikipedia. org/ wiki/ Yacc' rel=" nofol" > >yacc 或 < a href=" http:// en.wikipedia.org/wiki/ wiki/ GNU_bison" rel="no folf="http://en. wikipeedia.org/ org/ wiki/ Flex_lexalical_analyser" rel= "nofol folf" > > > > > a folex < folex < a > a tagystries " 树, 然后将此编成一个新的 SQL 字符串。 一旦你开始考虑加入这个表格, complem > translations a translations a true.

我所看到的许多项目都试图以某种中间形式来代表询问,例如结构(字段列表、表格名称、条件列表、条款中的ORDER列表等),然后在这些列表中添加新的条目(在查找列表中添加一个新条目以添加新的过滤器 ) 。 但是,回过头来看,这些表达方式与LINQ 的提供方式相比是苍白的。 我承认, LINQ 是一无是处或一无是处的提供, 而你要么是 < href="http://en.wikipedia.org/wiki/The_chicken_and_the_pig” rel=“nofollow” > 承诺 < /a> 自己或不是。 但是试图重新编辑它只揭示问题的复杂性。 今天,我会从另一端着手解决问题: 从 LINQ 开始, 并试图保持它处于偏僻状态, 不允许它发展成一种可怕的怪物, 无法控制查询生成工具, 使项目的每一层都添加一些过滤器到 Igury < /code>, 然后用一个没有最优化的服务器。

PS. < a href=>""http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/"rel="nofollow" '为什么我写AREL 是整个问题的一个很好的读物。

问题回答

您可以直接使用一个数据阅读器, 或者通过一个能进行低俗评估的分类进行。 见 < a href="http://msdn.microsoft.com/ en- us/library/haa3afyz(v=vs. 100. aspx) rel=" noreferrer" >http://msdn.microsoft.com/en-us/library/ha3afyz(v=s. 100. aspx)

所以作为一个粗略的例子,你可能会做这样的事情

public class LazyReader {
    SqlDataReader m_reader;
    SqlCommand m_command;
    SqlConnection m_connection;
    public LazyReader(SqlConnection connection, String sql)
    {
        m_command = new SqlCommand(sql, connection);
        m_connection = connection;
    }

    public IEnumerable<Object[]> read()
    {
        using (m_connection) {
            m_connection.Open();
            m_reader = command.ExecuteReader();
            while (m_reader.HasRows)
            {
                while (m_reader.Read())
                {
                    Object[] values = new Object[m_reader.FieldCount];
                    m_reader.GetValues(values);
                    yield return values;
                }
                m_reader.NextResult();
            }
            m_reader.Close();
        }
    }
}

您可能不得不对示例做一些乱七八糟的事情, 但是这个想法是使用一个 DataReader, 逐行阅读结果, 并通过一个可导致懒惰评估的IE 数返回收益 。 这样您就可以随处通过该 IE 数, 并随心所欲阅读 。 但要小心确保您阅读一致, 否则 SQLoncontect 将在30 秒后终止, 没有活动 。

为什么不只使用 Func Action Action 来定义查询, 并定义查询内容, 所以当您将其传递到下一个函数时, 必要时就可以执行 。

它的功能会像懒惰的装载。

您可以使用

Lazy< T> Lazy< T>

这一点。它依赖一个Func,正如詹姆斯建议的那样, 但也支持结扎和线条安全。

http://msdn.microsoft.com/en-us/magazine/ff898407.aspx" rel="no follow">http://msdn.microsoft.com/en-us/magazine/ff898407.aspx

EDIT:既然你现在正在寻找ORMS的其他特性,例如过滤和分类,但具有写原始 sql 的灵活性,我建议你研究一个ORM,例如实体框架或Nhibertate等ORM,并酌情使用其中一些原始 Sql 特性,例如

创建 SQL 查询( sql) ;

ORMS 还允许您在动态添加过滤器的位置时, 使用更强的打字来消除错误 。

Lazy<T> 类听起来和你正在寻找的相似。 正如凯多和詹姆斯所建议, 您需要定义一个方法来实际装载, 然后将其传递给您的懒惰( 真正初始化的) 对象的导体 。

特例 :

public class SomeClass
{
     Lazy<List<string>> myLazy = new Lazy<List<string>>(LoadData);
     private List<string> LoadData()
     {
        //open connection, execute your query, read/project data into a List, etc

        return new List<string> { "Hello", "My", "Name", "Is", "Earl" };
     }
}

Lazy<T> 类的行为与您可能预期的完全一样 - 它推迟一个包含对象的初始化, 直到通过 Value 属性被引用。 见 MDSN 引用 以获取更多信息

您可以在设计中考虑 < a href=> http://msdn.microsoft.com/ en- us/library/ff649690.aspx" rel = “ no follow” > Repositor status 。 存储库决定如何向客户类别提供东西。 如何做到这一点对消费者无关紧要, 消费者可以随身携带, 也可以在必要时注入 。

也考虑一个对象缓存, 如 < a href=" "http://redis.io/" rel="nofollow" >Redis 或 < a href="http://emcached.org/" rel="nofollow" >Memcached 。 如果您需要“ lazy load” 对象, 而不按顺序。 复杂的 SQL 查询可以只返回主键, 而不是几十个大数据字段。 保存所有查询的密钥, 然后根据需要创建商务对象 。

如果您比您的执行发育快, 仓库可以方便地改进, 而不会影响使用该仓库的班级 。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...