问题描述
在上一个问题中,我问了 orm 库是次优百家乐凯发k8的解决方案 并收到了很多很好的反馈.当我进一步考虑这个问题时,我得出结论,linqtosql(现在)和 linqtoentities(未来)的主要好处在于它们能够减少过程代码和 sql 之间的不匹配".鉴于 linqtosql 作为一种完整的数据查询语言的局限性,我不同意它的优势远不止于此,但我想知道其他人的意见.
in a previous question, i asked whether orm libraries were suboptimal solutions and received a lot of great feedback. as i've thought about the issue further, i've concluded that the primary benefit of linqtosql (now) and the promise of linqtoentities (down the road) lies in their ability to reduce the "mismatch" between procedural code and sql. given the limitations of linqtosql as a complete data querying language, i'm not inclined to agree that its advantages go much beyond this but i'd like to know others opinion.
首先,程序代码和 sql 之间的不匹配"是什么意思?如果您曾经开发过数据库应用程序,那么您可能已经熟悉(并且厌倦了)与数据库交互所需的步骤:设置所有参数,输入 sql 命令,然后将预期结果手动转换回变量或代码中使用的实例.
to start, what do i mean by a "mismatch" between procedural code and sql? if you have ever developed a database application then you have likely become familiar with (and weary of) the steps needed to interact with a database: set up all the parameters, enter the sql command, and then hand convert the expected results back to variables or instances used in code.
linqtosql 通过使用流畅"接口、lambda 表达式、扩展方法等使这变得更容易.最终结果是很容易将原生 c# 标量类型推送到数据检索调用中,并且易于自动生成原生c# 类实例.以微软网站上的这个例子为例:
linqtosql makes this much easier by the use of "fluent" interfaces, lambda expressions, extension methods, etc. the end result is that it is easy to push native c# scalar types into the data retrieval call and easy to automatically generate native c# class instances. take this example from the ms web site:
var q = from c in db.customers where c.city == "london" select c; foreach (var cust in q) console.writeline("id = {0}, city = {1}",cust.customerid, cust.city);
非常酷!
问题是什么?
好吧,正如我在链接到顶部的文章中指出的那样,存在许多问题.对我来说最大的 障碍是,任何在 sql 方面能力最低的人都会立即遇到障碍.不仅仅是作为 sql 替代方案而创建的许多结构不熟悉甚至笨拙(group by?我们在 linqtosql 中谈论丑陋).更大的问题是有许多常见的结构本身并不支持(例如 datediff).充其量,您可以从 linq 中逃脱"并将 sql 代码提交到 linq 调用流中.
well, as i pointed out in the article linked to at the top, there are a number of problems. the biggest showstopper for me was that anyone who is minimally competent in sql will immediately hit roadblocks. it isn't just that many of the constructs created as alternatives to sql are unfamiliar or even clumsy (group by? we're talking ugly in linqtosql). the bigger problem is that there are a number of common constructs that just aren't natively supported (e.g. datediff). at best, you can sort of "escape out" of linq and submit sql code into the linq call stream.
那么,简单地将 sql 嵌入 c#(或 vb)中,以允许您自由地声明您的 sql 但同时也为您提供简单的参数嵌入和自动转换为本机类不是更好吗?例如,如果我们在一个类中只实现六个函数,我们可以这样写(其中 qry 是我们查询类的一个实例):
so, isn't it better to simply embed sql in c# (or vb) in ways that permit you to freely state your sql but that also give you easy parameter embedding and automatic conversion to native classes? for example, if we implement just six functions in a single class, we can write something like this (where qry is an instance of our query class):
var listofenrollees = qry.command("select b.firstname, b.lastname, b.id from classenroll a inner join folder b on (a.clientid = b.clientid) ") .where ("a.classid", classid) .and() .append("(datediff(d, a.classdate, @classdate) = 0) order by lastname;") .paramval(classdate) .returnlist();
command 只是让我们开始收集 sql 语句,where 开始我们的 sql where 子句并输入第一个参数,append在更多 sql 上,paramval 只输入一个参数值来匹配上一行中找到的 sql 参数,而 returnlist 执行转换为类所需的魔法.请注意,这只是 sql:连接是微不足道的,支持 datediff(或任何其他 sql 构造)等.我们可以在 sql 窗口中对其进行测试,然后将其剪切并粘贴到我们的代码中,根据需要将其分解以输入我们的参数.再简单不过了.
the command simply starts us off collecting the sql statement, the where starts our sql where clause and enters the first parameter, append tacks on more sql, paramval just enters a parameter value to match the sql parameter found on the previous line, and returnlist does the magic needed to convert to a class. notice that this is just sql: joins are trivial, datediff (or any other sql construct) is supported, etc. we can test it out in a sql window and then just cut and paste into our code, breaking it up as appropriate to enter our parameters. it couldn't be easier.
现在,上面显示的基本构造对我来说似乎非常简单,它可以使用我已经拥有的 sql 知识来处理任何 sql 构造.我确实必须使用一些反射和一些其他很酷的新 c# 3 构造来使 returnlist(和类似的)调用工作,但总的来说,它非常简单.我还添加了一些花里胡哨的东西,使界面更加流畅.所以,这是我的问题,我希望听到社区的评论:
now, the basic construct shown above seems outrageously simple to me and it can handle any sql construct using the knowledge of sql i already have. i did have to use some reflection and some of the other cool new c# 3 constructs to make the returnlist (and similar) calls work but, overall, it was pretty straightforward. i also added a number of bells and whistles to make the interface more fluent. so, here is my question and where i'd love to hear comments from the community:
为什么我需要掌握 linqtoentities 的复杂性,甚至需要承担 linqtosql 的开销?这不是给了我 linqtosql 给我的一切吗?除了奇异的 relational to object 映射之外,它甚至不包括 linqtoentities 吗?
why would i ever need to master the intricacies of linqtoentities or even incur the overhead of linqtosql? doesn't this pretty much give me everything that linqtosql gives me and more? doesn't it cover even linqtoentities with the exception of exotic relational to object mappings?
更新:hamish smith 在下面认为 linq 可能有朝一日成为一种功能齐全的数据操作语言,功能强大到甚至不需要 sql.这是我没有讨论但我同意的一个重要的引爆点论点.我的立场的本质是,虽然 linqtosql 有一些实际优势,但它仍然离hamish 的目标很远.这是一个非常真实且重要的缺点.
update: hamish smith argues below that linq may someday be a fully capable data manipulation language so powerful that sql isn't even needed. this is an important tipping-point argument that i didn't discuss but with which i agree. the essence of my position is that, while there are some practical advantages to linqtosql, it still falls far short of hamish's goal. this is a very real and significant drawback.
hamish 还正确地指出,我仍在使用嵌入式 sql - 我还没有解决"这个问题.然而,对我来说,这是一个功能,而不是一个错误.sql 在选择和操作关系数据(毕竟,这是我们正在使用的数据)方面仍然要好得多,我希望能够使用它来制定我的百家乐凯发k8的解决方案.我认为嵌入式 sql 不是问题,而是它与 c# 之间的阻抗不匹配.但是,通过使用 c# 3 的受 linq 启发的新功能,我可以在很大程度上消除这种阻抗不匹配"并获得两全其美.
hamish also argues, correctly, that i'm still working with embedded sql - i haven't "solved" the problem. to me, however, this is a feature and not a bug. sql is still so much better at selecting and manipulating relational data (which is, after all, what we're working with) that i want to be able to use it to craft my solution. i'm arguing that embedded sql isn't the problem so much as the impedance mismatch between it and c#. however, by using the new, linq-inspired features of c# 3, i can largely eliminate this "impedance mismatch" and get the best of both worlds.
推荐答案
所以,简单地嵌入不是更好吗c#(或 vb)中的 sql 以允许的方式你可以自由地陈述你的 sql 但那还为您提供简单的参数嵌入并自动转换为原生课程?
so, isn't it better to simply embed sql in c# (or vb) in ways that permit you to freely state your sql but that also give you easy parameter embedding and automatic conversion to native classes?
我通常所做的与此非常接近.我在存储过程中编写 sql,因此我获得了真正 sql 的自由.在 c# 中,我使用 linq 的 dbml 以自然的方式访问存储过程.这感觉就像两全其美.
what i usually do comes very close to this. i write the sql in a stored procedure, so i get the freedom of real sql. in c# i use linq's dbml to access the stored procedures in a natural way. this feels like the best of both worlds.
对我来说,真正的百家乐凯发k8的解决方案看起来更简单:在 c# 代码中嵌入 sql 并让编译器生成强类.如果 visual studio 支持这一点,我怀疑有人会使用其他任何东西.
the real solution looks even simpler to me: embed sql in c# code and have the compiler generate the strong classes. if visual studio supported that, i doubt anyone would be using anything else.
(总是有人试图创建实体框架和架构"来消除对 sql 的需求.据我所知,这从来没有真正奏效过,只是因为结果很难维护并且速度很慢.)
(there' always people trying to create entity frameworks and "architecture" away the need for sql. as far as i know, this has never really worked, if only because the result is dramatically harder to maintain and dead slow.)