Posts Tagged ‘.NET 3.5’

Linq to SQL Quirks Part 4: Circular References

Friday, July 10th, 2009
This entry is part of a series, Linq to SQL Quirks»

In a project that I am working on at the moment, I have a situation where I have a Person table and a Family table.  The Person table has a FamilyID field, which is a foreign key to the Families ID (primary key) field, and the Family table has a DefaultPersonID, which is another foreign key back to Person to store the default contact for a family.

The problem is that if I create a new Person and Family with the Person being the DefaultContact, I get an InvalidOperationException thrown with a message “A cycle was detected in the set of changes”.  The problem is that Linq to SQL doesn’t know what to store first.  The only way that I have come up with to get around this is to do the following…

            If Person.ID = 0 AndAlso Not Person.Family Is Nothing Then

                Dim fam = Person.Family
                Person.Family = Nothing

                DBContext.SubmitChanges()
                Person.Family = fam

            End If

            DBContext.SubmitChanges()

This works by breaking the circular reference, so that there is only a 1 way reference, then submitting to the database, and once submitted, restoring the removed reference and submitting changes again

Linq to SQL Quirks Part 3 – Extension to Get Around the Delete Problem

Tuesday, June 30th, 2009
This entry is part of a series, Linq to SQL Quirks»

My previous post about problems deleting can be partly handled with an extension method to the Linq to SQL Table(Of T) class with something like this…

         Public Sub DeleteOnSubmitOrDetach(Of T As Class)(ByVal table As System.Data.Linq.Table(Of T), ByVal o As T)
            Dim IDProperty = o.GetType.GetProperty("ID")
            If IDProperty Is Nothing Then
                Throw New System.MissingFieldException("Trying to delete object of type " & GetType(T).Name & " - does not have an ID field")
            End If
            If IDProperty.GetValue(o, New Object() {}) = 0 Then
                table.InsertOnSubmit(o)
            End If
            table.DeleteOnSubmit(o)
        End Sub

Note that you’ll need to import System.ComponentModel and System.Reflection and possibly some others, and it assumes that you have an IDENTITY ID field by that name on all of your classes that you use this with.

Linq Part 3 – Query Format

Monday, June 29th, 2009
This entry is part of a series, Linq»

It is very easy when you are familiar with SQL to constrain yourself to treating Linq queries in a similar fashion and not take advantage of some of the new features that Linq allows. Of course, Linq does impose its own constraints, as does each Linq provider, so it isn’t always easier.

It is definitely worth getting your head around the fact that in Linq, you can query a query.  With some providers, this might mean that you are querying the results of a query, but with others, it can mean that you are simply building another query, which will only actually be executed when you try to retrieve the results.

For example,

Dim q = From p in DataContext.People Where p.Surname=”Smith”

q = From p in q Where p.FirstName=”John”

In Linq to SQL, this is perfectly efficient as it will only run SELECT * FROM Person WHERE Surname=’Smith’ AND FirstName=’John’ or something similar.

Equally, you can also combine multiple queries into a single statement, such as…

Dim q = From p in DataContext.People Select p.ID, p.Surname Order By p.Surname Select ID

…and of course you don’t need to worry about the order of the statements – notice a Select can come after an Order By!  The thing to remember is that each Select/Group effectively creates a different context (as in a variable context), so you have different variables available at each point in the query.

Linq Part 2 – From

Wednesday, June 24th, 2009
This entry is part of a series, Linq»

A Linq query will always start with From item in datasource

When I initially started using Linq, I thought that was a little odd, and why didn’t Microsoft just use SQL style Select columns from datasource.  I thought about this for a minute, and realised that the problem with that is that you can’t use Intellisense to get the column names because you don’t actually know what they are until you’ve specified the data source.

Another reason for this is that the Select part of a Linq query is not compulsory, so it makes more sense to start with the part that is.

You might find it a little confusing having to specify item if you are thinking in SQL terms, as you would usually just include a table name and possibly an alias in SQL.  The point in item is that a Linq query is a bit like a For loop in a single statement.  You are effectively looping around the items in the data source.  An individual provider might not actually implement it that way (Linq to SQL doesn’t – if you use a Where clause, it is translated to SQL instead of retrieving all the data and checking what matches), but that is the abstraction that we are using.  We don’t reference the item by using the datasource name because we might still want to access something else in the datasource separately in the query.

Linq to SQL Quirks Part 2: DeleteOnSubmit and Entity not Attached

Tuesday, June 23rd, 2009
This entry is part of a series, Linq to SQL Quirks»

If you use an implicit insert on a new object and then decide that you don’t actually want it, you have a bit of a problem.  First of all, you need to remove the relationships that you created so that it doesn’t show up in any places that it shouldn’t.  The problem with this is that Linq will still kind of (see below) have it marked for insertion, so if you call SubmitChanges without doing anything else, it will either still insert it, or if you’ve removed a relationship which relies on a non-nullable foreign key, you’ll get an error like

“An attempt was made to remove a relationship between a A and a B. However, one of the relationship’s foreign keys (A.BID) cannot be set to null.”

Where A and B are the 2 appropriate Linq to SQL classes.

The next thing we need to do then is to make sure that Linq to SQL removes the item from the insert list.  The only way that I have found to do this is to call DeleteOnSubmit on the appropriate table.  The problem is that if we do that at this point, we get an InvalidOperationException with message “Cannot remove an entity that has not been attached.”

Apparently, Linq to SQL knows it is supposed to insert it, but it isn’t properly attached.  To get around this, we need to call InsertOnSubmit on the appropriate table before calling DeleteOnSubmit.

That’s all fine and dandy and works, as long as you are trying to delete something that hasn’t been inserted yet.  Normally, however, I use the same code whether it has been inserted or not, and of course if you call InsertOnSubmit on an entity that has already been inserted, you get an InvalidOperationException saying “Cannot add an entity that already exists.”.  Therefore, before you call InsertOnSubmit, you need to check if it actually has already been inserted.  Since I always have identity fields with the name ID on all my tables and Linq to SQL updates these when it does an insert, I normally just check that the ID is 0 before inserting.

The resulting steps that you need to solve the problem are therefore: -

  1. Remove the relationships from item
  2. If the ID=0 then DataContext.Table.InsertOnSubmit(item)
  3. DataContext.Table.DeleteOnSubmit(item)

You shouldn’t actually have to call DataContext.SubmitChanges at this point – the whole point in the exercise is to mean it will be safe when you do later.

Alternatively, you can just throw away the datacontext without calling SubmitChanges, but I find that is rarely an option because there may be other data that needs submitting.

By the way, you need to do the first step of removing the relationships in order to make sure that none of your code accidentally tries to access the removed object as it will still be in memory as a related object until SubmitChanges is called otherwise and you could end up processing it when accessing entities related to an object that it is related to.

Linq to SQL Quirks Part 1: Implicit Inserts

Tuesday, June 23rd, 2009
This entry is part of a series, Linq to SQL Quirks»

There are a few things that Linq to SQL can be a bit funny about that aren’t so obvious.

First of all, there are what I call implicit inserts.  You might not have realised that you don’t actually need to explicitly call InsertOnSubmit on a table for Linq to SQL to do the insert as long as you have created a relationship to an object which already exists in the database.  Linq to SQL will automatically insert the new object on the next SubmitChanges call.

More details on installing .NET 3.5 in Windows 2000

Wednesday, April 22nd, 2009

I’ve had a comment that my previous post explaining how to install .NET 3.5 in Windows 2000 wasn’t very clear, so I’ll try to clarify it a little…

First of all, let me explain how it works.  .NET is actualy 2 separate things.  There is the .NET runtime, which deals with interpreting the MSIL intermediate code and executing it.  There is also the .NET Framework, which are all the libraries containing the classes that you usually code with in .NET.

In theory, the .NET runtime can be used without the .NET framework (although you’d probably need a couple of DLLs to define things like the basic types).  You could use an entirely different framework which sits on top of the same runtime and is compiled to MSIL.  I’m not aware of any that exist though.

The really interesting bit is that there are actually only 3 versions of the .NET runtime – 1.0, 1.1 and 2.0.  1.0 and 1.1 are used for the corresponding framework versions, but 2.0 is used for running framework 2.0, 3.0 and 3.5.  

In fact, in terms of the framework, 3.0 is 2.0 plus some extra stuff, and 3.5 is 3.0 plus extra stuff.  The trick which I rely on is that you can install 2.0 in Windows 2000 and just add the extra stuff that you need. 

For my purposes, all I needed was support for Linq and Linq to SQL and a few other bits and bobs.  All this is available in .NET Assembly DLL files.  you just need to make sure that the assemblies are available to be loaded by the application you are running.  

You also need to make sure that you have any prerequisites for those assemblies, because a lot of them will access classes in other assemblies.  There are 2 ways of dealing with that.  You can either copy in the entire set of DLLs, or you can keep running your program and looking to see what assembly it can’t find when it throws an exception, copying that DLL in and re-running it until you don’t get any more exceptions.

There are 2 ways of making the assemblies available to your program.  You can either register them in the GAC so that they can be accessed from anywhere (I’ve not tried this and I probably wouldn’t recommend it – if you want to know how to do this, google installing an assembly in the GAC), or you can just copy them into the application folder that your EXE sits in (or bin folder on your ASP.NET website will probably work too).  This does make for a lot of files in that folder, but it works!

You should be able to find the .NET 3.5 assemblies in a folder on a PC that has .NET 3.5 installed under

Program Files\Reference Assemblies\Microsoft\Framework\v3.5 

nb. Make sure that you have Windows 2000 SP4 and .NET framework 2.0 SP1 installed on the Windows 2000 PC!  You might also need to install KB 835732 before .NET 2.0 SP1.

Linq Part 1 – What is Linq?

Tuesday, March 24th, 2009
This entry is part of a series, Linq»

Linq is an abbreviation for Language Integrated Query.  The idea of it is that you can write a query on a source of data inline as part of your code.  It is particularly clever because Linq allows different providers to be used so that different types of data can be queried.  There are Linq providers that are part of the .NET Framework for querying anything based on IEnumerable (including Lists, Collections, Arrays, etc.), XML, SQL Server databases (using Linq to SQL). 

There are also providers available for querying Oracle, MySQL, various webservices (one of the earliest ones I came across was Linq to Amazon).  It is a very powerful system with lots of flexibility.

Another point about Linq is that you can build queries on top of queries and depending on the provider, it only compiles and executes the final query when you try to access the data.  For example, you could do a query like

Dim people = From p in DB.People Where p.FirstName=”John”

people = From p in people Where p.Surname=”Smith”

Once you try to access people, (eg. by looping through it), Linq will execute an SQL query something like

SELECT [ID], [FirstName], [Surname] FROM [Person] WHERE [Person].[FirstName]=’John’ AND [Person].[Surname]=’Smith’

.NET 3.5 SP1 in Windows 2000

Monday, March 23rd, 2009

I’ve posted a couple of times earlier on .NET 3.5 in Windows 2000.  The .NET framework 3.5 sits on .NET 2.0 SP2, which is only available to install on Windows XP and onwards.  However, from experimentation, this does not mean that the same tricks don’t work.  As long as you have .NET 2.0 SP1 installed, you can get away with copying most of the DLLs in with no trouble.  It also seems to work with some of the newer ones.

Update on .NET 3.5 in Windows 2000

Monday, March 2nd, 2009

This has now been running fine for a couple of months and is being used on a day to day basis.  Not all functionality works perfectly out of the box, but most of the stuff I have tried can be worked around.  I’m using compilation on the fly using the VB.NET 3.5 compiler to make dynamic Linq to SQL queries, which I have needed to create a workaround using vbc.exe – the VB.NET compiler and passing in command line parameters.  I needed to copy in the required DLLs that it was complaining that it didn’t have, and a few extras as well that I threw in predicting that it might need them.  Let me know if you want more details – comment below.