We have some legacy code that uses Linq to SQL as the ORM. We'd like to migrate this logic to .Net Core so that we can house it on a linux server. As far as I can tell, L2S is not included in .Net Core.
What is the migration path of least resistance?
If you used L2S because EF is inefficient at using Skip and Take for fetching large results as chunks, then your best bet is Dapper. Get yourself a copy of LINQPad and use it to get the generated SQL for each of your LINQ expressions.
L2S wraps some bizarre SQL around the actual query to use SQL's rownumber function to implement skip and take. If you are using the latest version of SQL Server then you don't need this because TSQL now has clauses equivalent to skip and take. This is handy if you are writing SQL directly and produces comprehensible SQL that won't induce WTF in those who follow, but the LINQ way works on all versions of SQL Server.
Then use this SQL with Dapper, which will do the ORM part for you. It also has proper support for type mapping parameters similar to L2S so you can avoid building SQL strings and injection vulnerabilities.
If you want all the smarts for constructing object graphs with FK values implied by collection membership then you're out of luck, you'll have to code it by hand.
update 2018-05-11
EF is less horrible than it used to be. EF Core is simpler than EF while retaining many of the benefits. I am currently using EF Core on a project at work and it's not the disaster EF once was.
I did have to help with an outer join. Left to its own devices, LINQ fetched the inner part and then for each inner row ran a separate query for its outer portion.
I fixed this by explicitly fetching the inner part and constructing a keyset as an array of int. Another LINQ statement fetched all of the outer rows exploiting the fact that Array.Contains maps to IN which uses indexes. Then I materialised both parts using ToArray() and used LINQ to join them in memory. This brought execution time down from ten minutes to 300ms.
You shouldn't have to do this; L2S wouldn't have cocked it up in the first place. But at least there's a straightforward general solution.
A shortcoming of my solution is that it is not well adapted to progressive fetch.
update 2020-06-12
Dapper can return dynamic results. I find this is a good bridge between SQL and C#. The columns and their names are governed by the SQL. This can be a little fragile since C# is case sensitive and SQL isn't, but with the SQL in your code you can at least see what it is and fix it.
More to the point, you can use LINQ directly on these dynamic results.
DevArt's LinqConnect now support .NET Core as of May 2017:
https://www.devart.com/news/2017/net-core-support.html
It's a drop in replacement for Linq To Sql and it even dislocates you from MS SQL Server if you so wish!
If you are rewriting legacy code to .NET Core, this will take some effort to being with.
And for L2S, you will probably need to rewrite this into modern queries using Entity Framework Core. It might make your life easier generating entities from database though, see Reverse engineer your model.
This would be the recommended way, however I am not sure if it's the easiest one in your case.
Related
What are the advantages of EF4 and under what circumstances is it preferred over LINQ to SQL?
LINQ to SQL will have no more future development. So EF is the way to go in the future.
Entity Framework vs LINQ to SQL (this should explain what you want to know)
Well, two of the major differences are:
1) EF can target multiple database engines, including Oracle and MySQL. Not just MS SQL Server.
2) You can do so-called "code first" schema development. Basically you create your object model, and along with some hints, EF will generate the schema for you.
Seems to me that Linq to Sql is great for rapid prototyping and simple CRUD scenarios. Anything more advanced or enterprisey would use EF4. (Or at least that's what MS would like us to believe :) I've had good luck with Linq to SQL in production, for what it's worth.
EF4 basically adds a whole bunch of OO-ness to the mapping that isn't present in LINQ-to-SQL, such as rich object inheritance models. My own take on it is that none of that is necessary for good design, and I have yet to come across a single scenario in my own work that warrants the added complexity EF4 brings to the table.
Having said that, Microsoft has deprecated LINQ-to-SQL and will not continue developing it, so it will eventually fall behind EF4 in capability and efficiency (if it hasn't already). So the pragmatic choice is simple: go EF4.
After trying both and spending over one weeks porting a project from linq to sql, I can say that I really prefer Linq to SQL. The main reason for this is that EF is more restrictive on what functions you can use in LINQ queries. In EF I had to cast my linq expressions to a list to be able to manipulate them any further. Sorry for not being able to remember any example, it's been a few months since I did this...
One of the really big plus sides for EF, is the ease of use in connection with WCF Data Services. Very handy if you are developing a web site that should have an RESTful API.
Also, even though Linq to SQL is quite mature, it is indeed a dying technology. It won't get any significant updates, that makes it harder to commit to Linq To SQL for a new project.
We're working on an ASP.NET web application with C# code behind. The database is MySQL 5.1 using InnoDB. The data access layer uses ADO.NET to call stored procedures and then builds various data structures out of the result sets (no object mapping). This works fine, but it is a little verbose.
Not surprisingly, we made some mistakes when designing the first version of our data model, but the experience has made us smarter and we decided to refactor the data model. We don't have to change our data access layer, but we are considering our options for that as well.
It's been difficult for us to ignore the popularity of ORM tools these days; we feel like we are way behind or something for not being familiar with them. Not only that, but we have already designed an object model that nicely describes our data model. The main ORM tools we would consider are NHibernate, ADO.NET Entity Framework, and LINQ to SQL. We would prefer LINQ to SQL because we have read (on S.O.) that it is more light weight than full ORM tools.
We think one drawback to using an ORM tool is the learning curve, but we can already see how using LINQ could reduce the amount of code we will have to write, which could save us time in the long run. However, we are using MySQL, not SQL Server.
So my question is, would DBLinq work well enough for a production system? Or, is LINQ to SQL a compeling enough reason for us to make the move to SQL Server 2008? Incedentally, I'd prefer to use SQL Server over MySQL, but cost is the obvious drawback. After 3 years on BizSpark, we'd be on the hook for $6K. Or, should we consider other ORM tools instead? Or, should we just ignore the hype and not use an ORM tool, but maybe take advantage of LINQ to DataSet?
I searched S.O. for info on DBLinq, but only found 17 questions with the DBLinq tag, so it doesn't appear to be popular.
EDIT
Looks at though dotConnect for MySQL has support for LINQ, so that's another option.
Can anyone speak to how well that driver works for writing LINQ queries?
Check bl-toolkit. It's free, very fast and has great LINQ support. Newest addition are T4 templates for generating your data model from database.
What are the pro's and con's of using "Linq to SQL" and core ADO.NET technology for access databases?
Advantage
No need to create business objects dbml files will do for you
No need to worry about writing queries because linq2sql convert your statment in efficient queries
Important is Lazy Loading of related objects
Disadvantage
Disconnect linq is not supported i.e you cannot deatch you objects form DataContext object. for more detail : Most efficient way to update with LINQ to SQL
I have the same view point as this post, I've yet to find any major disadvantages of Linq.
I have built a number or application and websites using Linq and found it to be extremlly simple to use
http://forums.asp.net/t/1520157.aspx
comment by BoogleC
Regards
Sp
Id also be carefull about how you write you LINQ statement. Sometimes its better to compile your Linq rather than not as every single run of the Linq query is fully parsed every time it happens. See below linq
http://www.codinghorror.com/blog/2010/03/compiled-or-bust.html
I wouldn't recommend LINQ to SQL at all as it is effectively dead (you don't want to be writing legacy code, right?). Microsoft is no longer developing it and they recommend using the Entity Framework instead (see here), however, if you are interested in using an ORM, I would strongly recommend looking at NHibernate.
I'll just put it out there that I'm new to LINQ to SQL. Hell, i'm relatively new to programming in general.
Anyways, I would like to learn and use LINQ to SQL to a project that was built using .NET 2.0 Framework. The project uses stored procedures to access the database (there's no dynamic SQL queries on the front end servers). LINQ to SQL seems a great alternative to stored procs but to introduce it to my project would break the principle of 'Separation of Concern'. Would it be best to not break this principles and just write more stored procedures when needed? Or is there a way to use LINQ to SQL without breaking the principle?
I generally find it hard to add new technology and tools in legacy projects without breaking the consistencies in projects.
Having code which interacts with the database server through SQL instead of through stored procedures is not a violation of separation of concerns, as long as that code is well modularized and the LINQ to SQL part cares only about data entry/retrieval and is not intermingled with other tasks (concerns). LINQ to SQL usage does not break any principle
Now, modifying code not to use SPs when it has been coded that way from the beginning will probably not be a small task and there might not be any real benefit in the end other than you learning LINQ to SQL.
Actually, LINQ to SQL helps a great deal with SoC. It separates the fact that you are using SQL from your domain objects even more than a traditional sproc-based DAL. Having a bunch of methods which call into stored procedures is a poor-man's attempt at the same thing - minimizing but not eliminating contact points between the DAL and the business logic. The LINQ to SQL library becomes your DAL, and you're free to manipulate a bunch of stupid objects with no direct ties to any data backing - with the added benefit of being able to express directly against your domain objects using LINQ expressions, instead of relying on the pre-determined permutations of stored procs.
If the project is a large one and uses many sprocs then it is not a smart idea to replace it's sprocs with LINQ. The reasons should be obvious why it is not prudent to do so. However, moving forward, this in no wise means you shouldn't implement a layer for LINQ. This is what I have done with some of my larger legacy apps. Implementing and using LINQ is well worth the effort, but it is not worth the effort (nor worth the risk) to rewrite old sprocs to use LINQ.
My team is developing a large java application which extensively queries a MySQL database (in different classes and modules).
I'd like to known if there is a pattern that allows me to be notified at compile time if there are queries that refer to a wrong table structure (for instance if I remove or add a field on a table and the query string refers to it), in order to prevent runtime errors.
This should work also for JOIN queries.
Querydsl is similar to LiquidForm and supports both JPA / Hibernate and SQL based backends.
For the SQL based version we currently support MySQL (5.? tested), Oracle (10g tested) and HSQLDB.
In a nutshell a query like this
select count(*) from test where name = null
would become
long count = query.from(test).where(test.name.isnull()).count();
Querydsl SQL uses code generation to reflect SQL schemas into Java classes.
There's an open-source tool called DODS (Data Object Design Studio) that could do what you want. The DODS tool was originally part of the Enhydra Java application server project, and since the company backing that project went kablooey in 2002, DODS has been hosted and maintained at ObjectWeb. Anyway, it's open-source (LGPL).
http://forge.objectweb.org/projects/dods
The concept is that you describe your schema in an XML file, and DODS generates Java POJO classes with which you can query and manipulate the database tables. Of course every time you change your schema, you need to run DODS again to re-generate the ORM classes, and recompile your app against them.
But the result is that if a table or column disappears, and your app is querying database metadata that no longer exists, you do get a compile-time error, because your code is now calling a corresponding class or method that no longer exists.
I would say that the simple answer is "no". The more complete answer is "yes, to some degree", depending on your willingness to jump through hoops.
Unless you have a java representation of your database schema you will never be able to get compile time notification if your queries are wrong (these classes can be generated). Also, you must use these classes to build your queries, so the method you use today (query strings) must be abandoned. To be able to use the java classes to build your queries, you must also use tricks. LiquidForm uses the required tricks to build JPA queries, but I have not seen a similar library for constructing SQL queries (LiquidForm is new and quite brilliant). You would actually have to build a similar library yourself. So, as you see, getting compile time warnings when constructing SQLs is hard, but not impossible (only nearly impossible). But even if you should be able to create what I suggest, your java representation of the schema must be updated immediately after a schema change, so the generation of java classes would have to be built into your IDE or build tool.
I would suggest you rather have good unit tests that will notice when your queries become illegal as a result of schema change. This is the most common way to achieve what you want. Also, should you decide to "upgrade" to JPA, you could use LiquidForm to get what you want.