The mysteries of software development and networking... RSS 2.0



 Tuesday, June 02, 2009

I guess the success for LINQ to SQL makes it hard for Entity Framework to absorb the full feature set in a single (v2) release. The team has been working on a bunch of fixes and improvements to be delivered in .NET 4.0.

Here is the list as posted by Damien:

LINQ to SQL changes in .NET 4.0
Change list
Performance
  • Query plans are reused more often by specifically defining text parameter lengths
  • Identity cache lookups for primary key with single result now includes query.Where(predicate).Single/SingleOrDefault/First/FirstOrDefault
  • Reduced query execution overhead when DataLoadOptions specified (cache lookup considers DataLoadOptions value equivalency – post beta 1)
Usability
  • ITable<T> interface for additional mocking possibilities
  • Contains with enums automatically casts to int or string depending on column type
  • Associations can now specify non-primary-key columns on the other end of the association for updates
  • Support list initialization syntax for queries
  • LinqDataSource now supports inherited entities
  • LinqDataSource support for Dynamic Data query extenders added
Query stability
  • Contains now detects self-referencing IQueryable and doesn't cause a stack overflow
  • Skip(0) no longer prevents eager loading
  • GetCommand operates within SQL Compact transactions
  • Exposing Link<T> on a property/field is detected and reported correctly
  • Compiled queries now correctly detect a change in mapping source and throw
  • String.StartsWith, EndsWith and Contains now correctly handles ~ in the search string
  • Now detects multiple active result sets (MARS) better
  • Associations are properly created between entities when using eager loading with Table-Valued Functions (TVFs)
  • Queries that contain sub-queries with scalar projections now work better
Update stability
  • SubmitChanges no longer silently consumes transaction rollback exceptions
  • SubmitChanges deals with timestamps in a change conflict scenario properly
  • IsDbGenerated now honors renamed properties that don't match underlying column name
  • Server-generated columns and SQL replication/triggers now work instead of throwing SQL exception
General stability
  • Binary types equate correctly after deserialization
  • EntitySet.ListChanged fired when adding items to an unloaded entity set
  • Dispose our connections upon context disposal (ones passed in are untouched)
SQL Metal
  • Foreign key property setter now checks all affected associations not just the first
  • Improved error handling when primary key type not supported
  • Now skips stored procedures containing table-valued parameters instead of aborting process
  • Can now be used against connections that use AttachDbFilename syntax
  • No longer crashes when unexpected data types are encountered
LINQ to SQL class designer
  • Now handles a single anonymously named column in SQL result set
  • Improved error message for associations to nullable unique columns
  • No longer fails when using clauses are added to the partial user class
  • VarChar(1) now correctly maps to string and not char
  • Decimal precision and scale are now emitted correctly in the DbType attributes for stored procedures
  • Foreign key changes will be picked up when bringing tables back into the designer without a restart
Code generation (SQL Metal + LINQ to SQL class designer)
  • Stored procedures using original values now compiles when the entity and context namespaces differ
  • Virtual internal now generates correct syntax
  • Mapping attributes are now fully qualified to prevent conflicts with user types
  • KnownTypeAttributes are now emitted for DataContractSerializer with inheritance
  • Delay-loaded foreign keys now have the correct, compilable, code generated
  • Using stored procedures with concurrency no longer gets confused if entities in different namespace to context
  • ForeignKeyReferenceAlreadyHasValueException is now thrown if any association is loaded not just the first
Potentially breaking changes

We worked very hard to avoid breaking changes but of course any potential bug fix is a breaking change if your application was depending on the wrong behavior. The ones I specifically want to call out are:

Skip(0) is no longer a no-op

The special-casing of 0 for Skip to be a no-op was causing some subtle issues such as eager loading to fail and we took the decision to stop special casing this. This means if you had syntax that was invalid for a Skip greater than 0 it will now also be invalid for skip with a 0. This makes more sense and means your app would break on the first page now instead of subtlety breaking on the second page. Fail fast :)

ForeignKeyReferenceAlreadyHasValue exception

If you are getting this exception where you weren’t previously it means you have an underlying foreign key with multiple associations based on it and you are trying to change the underlying foreign key even though we have associations loaded.Best thing to do here is to set the associations themselves and if you can’t do that make sure they aren’t loaded when you want to set the foreign key to avoid inconsistencies.

Tuesday, June 02, 2009 7:48:30 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ
 Monday, April 06, 2009

Yeah, my last Training Kit is shipping!

Get a copy now at Amazon: http://tinyurl.com/dxwdz5

Monday, April 06, 2009 2:21:19 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.NET | C# | General | LINQ
 Monday, March 23, 2009

The documentation doesn't specifiy it but in the Entity Framework when you call ObjectContext.SaveChanges the update is 'wrapped' in a transaction.

NorthwindIBModel model = new NorthwindIBModel();

Guid id = Guid.NewGuid();

model.AddToCustomer(new Customer() { CustomerID = id, ContactName = "Andrew", CompanyName = "Northwind Traders" });
model.AddToCustomer(new Customer() { CustomerID = id, ContactName = "Aikido", CompanyName = "Northwind Traders " });

model.SaveChanges(); // exception duplicate key - transactional -> no changes to the database

Monday, March 23, 2009 9:45:21 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.NET | C# | LINQ
 Monday, December 08, 2008

I just send the last revision of my chapters for TK 70-561 to the editor. Yeah! Hopefully the book will go to print soon. You can pre-order already on Amazon!

Cover-TK70-561

For me the last chapter to work on was LINQ to SQL, but the book includes chapters on learning ADO.NET, Typed DataSets, LINQ to SQL and Entity Framework. You'll need to know it all. :-)

Stephen Forte has an interesting post on the relevance of LINQ to SQL.

Monday, December 08, 2008 11:31:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2] -
General | LINQ
 Sunday, November 30, 2008

The DataContext.SubmitChanges() method will update the database in the following order:

- Perform all inserts
- Perform all updates
- Perform all deletes

Running SQL Profiler while running the following code will first perform all inserts on product, then the updates and the deletes. Also note that SubmitChanges will perform a batch update (which is good). The SubmitChanges is a single statement, but it does not implement a transaction, so if you want a rollback to occur if an exception occurs (for instance a foreign key violation) then you'll need to use a TransactionScope.

public void UpdateOrders()
{
    using ( var db = new VideoGameStoreDBDataContext() )
    {
        var query =  from p in db.Products
                    select p;
 
        foreach(var product in query)
        {
            product.ListPrice = product.ListPrice * 1.1;
            if ( product.ListPrice > 400 )
            {
                db.Products.DeleteOnSubmit( product );
            }
        }
 
        ProductType game = (from pt in db.ProductTypes 
                         where pt.ProductTypeName == "Game"
                         select pt).Single();
 
        Product newProduct = new Product()
        {
            ProductName = "Travian",
            ListPrice = 20,
            ProductType = game,
            ProductDescription = "Online Game",
            ProductTypeID = 1,
            ListPriceCurrency = "$"
        };
 
        db.Products.InsertOnSubmit( newProduct );
        db.SubmitChanges();
    }
}
Sunday, November 30, 2008 6:20:00 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
LINQ
 Saturday, November 01, 2008

It would appear that LINQ to SQL is running on a dead end track.

At PDC the announcement was made that no more investments in LINQ to SQL are made and the Entity Framework will absorb any features that LINQ to SQL has and that are worth preserving.

The following message from Tim Mallalieu says it all:

Is LINQ to SQL Dead?

We will continue make some investments in LINQ to SQL based on customer feedback. This post was about making our intentions for future innovation clear and to call out the fact that as of .NET 4.0, LINQ to Entities will be the recommended data access solution for LINQ to relational scenarios. As mentioned, we have been working on this decision for the last few months. When we made the decision, we felt that it was important to immediately to let the community know. We knew that being open about this would result in a lot of feedback from the community, but it was important to be transparent about what we are doing as early as possible.  We want to get this information out to developers so that you know where we’re headed and can factor that in when you’re deciding how to build future applications on .NET.  We also want to get your feedback on the key experiences in LINQ to SQL that we need to add in to LINQ to Entities in order to enable the same simple scenarios that brought you to use LINQ to SQL in the first place.

Saturday, November 01, 2008 5:26:24 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2] -
LINQ
 Sunday, October 26, 2008

After discovering that the LINQ to SQL Designer will only support tables from a single data source I set out to manually implement a cross database query using two data contexts.

The result is the following query which joins orders in the OrderDB to products in the VideoGameStoreDB.

public List<Order> FindOrders( string typename )

{

    try

    {

        var productdb = new VideoGameStoreDBDataContext();

        var orderdb = new OrderDBDataContext();

 

        var query  = from o in orderdb.Orders

                     join p in productdb.Products on o.ProductID equals p.ProductID

                     where p.ProductType.ProductTypeName.Contains( typename )

                     select o;

 

 

        return query.ToList();

    }

    catch ( Exception exception )

    {

        Trace.WriteLine( exception );

        throw;

    }

}

 

LINQ to SQL is unable to resolve this query, even though both databases sit on the same server. The compiler will however not warn you not to do this, instead a runtime exception with message 'The query contains references to items defined on a different data context.' occurs.

In a scenario like this the only solution appears to be to write a stored procedure which can perform the cross database query and use that stored procedure from a data context.

Sunday, October 26, 2008 5:16:21 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
C# | LINQ

The LINQ to SQL Designer supports just one connection, which makes sense since a LINQ DataContext is scoped to one connection. The designer does offer to change the connection string for you, but I guess making cross database queries is not possible using the designer.

The following message is what you get when dragging a table from a second data source onto the design surface.

image

Sunday, October 26, 2008 4:25:01 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | LINQ

I just discovered that the LINQ to SQL Designer does not support User Defined Types.

The following message appears when I try and add a table from my database to my design surface. The Customer table in question has a UDT named 'Point' to specify the GPS location of the business.

image

Sunday, October 26, 2008 4:17:42 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | LINQ
 Saturday, October 25, 2008

With LINQ to SQL you can choose to use an external mapping file, allowing you to map SQL statements to CLR objects (also referred to as POCO, Plain Old CLR Objects). Doing so means you do not need to adorn your classes with attributes.
Here's a little sample of how to do this.

public class Supplier
{
    public int ID { get; set; }
    public string Name { get; set; }
}
 
public List<Supplier> GetSupplier( string name )
{
    SqlConnection conn = new SqlConnection( cConnectionString );
 
    XmlMappingSource xms = XmlMappingSource.FromUrl( @"mapping.xml" );
 
    var db = new DataContext( conn, xms );
 
    Table<Supplier> Suppliers = db.GetTable<Supplier>();
 
    var query = from s in Suppliers
                where s.Name == name
                select s;
 
    return query.ToList();
}
 
 

The XML can be as simple as:

<?xml version="1.0" encoding="utf-8"?>
<Database Name="VideoGameStoreDB"
          xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
  <Table Name="dbo.Supplier" Member="Supplier">
    <Type Name="Supplier">
      <Column Name="SupplierID" Member="ID" />
      <Column Name="SupplierName" Member="Name"  />
    </Type>
  </Table>
</Database>
 

You can use SQLMetal (a command line tool included with Visual Studio) to generate a mapping file.

Saturday, October 25, 2008 8:27:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | LINQ
 Friday, May 09, 2008

Okay, so you read the title of this post. Perhaps you're expecting huge amounts of code, but guess what. As it turns out, this is so ridiculously easy. This will be a very short post.

Step one is to have a method that loads an RSS feed. WCF offers a new class called SyndicationFeed.

private SyndicationFeed Load( string url )

{

  XmlReader reader = XmlReader.Create( url );

  SyndicationFeed feed = SyndicationFeed.Load( reader );

  return feed;

}

 

The above method will take a url and use to load a feed. Now suppose I have a list of urls and I want to take all the items in all the feeds, sort them and use them to generate a new, aggregated feed. Sounds like a fair amount of work, right.

Here is the code:

 

private SyndicationFeed Aggregate( List<string> urls )

{

  var items = from url in urls

              from item in Load( url ).Items

              orderby item.PublishDate descending

              select item;

 

  SyndicationFeed feed = new SyndicationFeed( items );

  return feed;

}

 

Cool!

Friday, May 09, 2008 11:10:19 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | LINQ | WCF
 Monday, April 21, 2008

The Maine Developer Network is hosting a Geek Lunch tomorrow at the State of Maine, Harlow Building at 18 Elkins Ave in Augusta.
Chris Bowen will be presenting on LINQ & Language Improvements in C# 3.0/VB 9.
Sign up here.

LINQ (Language Integrated Query) is a unified approach for querying data using coding syntax that remains consistent regardless of the data source. It WILL change the way you work as a developer and architect and this session will help you on your way to using it effectively. To understand how LINQ works, we'll first navigate the new features of C# 3.0 and VB 9.0 that enable LINQ functionality. Then, we'll dive into .NET 3.5 and Visual Studio 2008 to explore the various realms of LINQ: Datasets, XML, Database/SQL, in-memory objects, and more. By the end of this session, you'll have a solid understanding of how LINQ works and what it can do for your applications.

Monday, April 21, 2008 8:50:10 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | General | LINQ
 Thursday, March 27, 2008

Since I was looking at books today anyway I thought I'd research what is available C# 3.0, I haven't read any of these yet, but check them out:

Thursday, March 27, 2008 12:34:28 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | LINQ
 Monday, March 24, 2008

The 22nd of April the Maine Developer Network is organizing a Geek Lunch. We'll be meeting at the State of Maine offices in Augusta to listen to Chris Bowen present on LINQ & Language Improvements in C# 3.0/VB 9.

Pizza will be provided and attendance is free and open for everyone!

More info and RSVP here.

Monday, March 24, 2008 11:52:01 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | General | LINQ
 Sunday, November 11, 2007

Earlier this year the C# team implemented a change in the design of anonymous types. It used to be possibly to create an anonymous type and then change a property on the anonymous type. The code would look like this:

var x = new { Name = "Mark", Age = 0 };
x.Age = 35;

In Visual Studio 2008 beta 2 this is however no longer possible since anonymous types are now immutable. There are apparently good reasons for doing this and Sree explains it in this post and there is an issue on MSConnect where Mads from the C# team explains the reasoning. Must say I don't completely get the reasoning, especially since VB.NET does not have this restriction.

Sunday, November 11, 2007 11:23:02 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C# | LINQ

The website www.hookedonlinq.com has an excellent article explaining the basics of LINQ to SQL. It's called LINQ to SQL - 5 minute overview.

Sunday, November 11, 2007 10:47:56 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ

If you want to join data which is in a list with data that is in the database, then you need to use the 'Contains' operation.

The code below shows that we have a list containing two values, next we want to join this list with some data in the database. This data has an Id and an Description.
You might be tempted to use the join operator, but that will fail, instead, call the Contains() method.

static void Main(string[] args)
{
    List<int> l = new List<int>();
    l.Add(1);
    l.Add(2);

    CustomerInfoDBDataContext db = new CustomerInfoDBDataContext();
    var result = from pi in db.PersonalInfos
                 where l.Contains(pi.Id)
                 select pi.Id + " - " + pi.Description;

    foreach (var info in result)
    {
        Console.WriteLine(info);
    }
    Console.ReadLine();
}

Sunday, November 11, 2007 10:39:03 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ

Niels confirmed it for me. Yes, it is possible to run a LINQ to SQL query in SQL Server 2008 using a .NET managed stored procedure.

As he puts it: "yes you can - but as soon there are any transactions invloved things will go pear-shaped".

Note that there will also be an optimized LINQ to SQL provider as part of SQL Server 2008:

"Language Integrated Query (LINQ) enables developers to issue queries against data by using a managed programming language such as C# or Visual Basic.NET, instead of SQL statements. LINQ enables seamless, strongly typed, set-oriented queries written in .NET Framework languages to run against ADO.NET (LINQ to SQL), ADO.NET DataSets (LINQ to DataSets), the ADO.NET Entity Framework (LINQ to Entities), and to the Entity Data Service Mapping Provider. SQL Server 2008 features a new LINQ to SQL Provider that enables developers to use LINQ directly on SQL Server 2008 tables and columns."

Sunday, November 11, 2007 8:01:04 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ | SQL

Yesterday I spoke at the iSDC and Ronua Community Workshop. We had a great day and it was a pleasure meeting the people at iSDC, meeting the developers in Cluj and surroundings (some drove over 200km to make it to the meeting) and Petru Jucovschi (the DPE for Microsoft Romania).

Here are the two presentations that I did:

11-09-2007 - Developing Windows Vista gadgets.pptx (431.43 KB)

11-10-2007 - 2008.NET.pptx (252.91 KB)

In the Visual Studio 2008 presentation I also talked about the work I've done for AOL. The AOL developer site can be found at http://dev.aol.com and for more reference material on Vista gadgets you can visit my AOL blog.

Sunday, November 11, 2007 3:32:20 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2] -
C# | General | LINQ | Vista | WCF

During my session yesterday at the iSDC and RONUA Community Workshop I received a question on how to do a group by together with calculating the sum of the group.

I couldn't remember the right syntax and had to go and look it up. There is actually a sample included on the 101 Linq Samples page (thanks Dragos!).

The query looks like this:

public void Linq80() {
   List products =
GetProductList();

   var categories =
      from p in products
      group p by p.Category into g
      select new {Category = g.Key, TotalUnitsInStock = g.Group.Sum(p => p.UnitsInStock)};

   ObjectDumper.Write(categories);
}

Sunday, November 11, 2007 3:14:02 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ
 Thursday, January 19, 2006

Follow this link to view the recent episode of MSDN TV where they discuss LINQ for VB.NET.

Overview
Visual Basic 9.0 will offer radical improvements in its ability to work with data in all its forms: as objects, as XML, and as relational data. Paul Vick and Amanda Silver discuss the latest Customer Tech Preview of the next version of Visual Basic to hit the Web. It includes support for DLinq (language integrated query over relational data) and expanded editor support for query statements and integrated XML.

Thursday, January 19, 2006 2:09:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ
 Saturday, January 14, 2006

Just a couple of links to stuff that's in beta right now:

WinFX, XAML and SDK
ASP.NET ATLAS
C# and LINQ
VB.NET and LINQ

Saturday, January 14, 2006 10:37:48 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.NET | C# | LINQ | WPF

I'm finally catching up on some reading that I've been meaning to do.

Right now I'm reading 'Programming Windows Presentation Foundation' by Chris Sells & Ian Griffiths. Good read and I hope to finish it on my next flight :-)

Also spend some time this morning reading an article by Ted Neward on MSDN (http://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dndotnet/html/linqcomparisons.asp) which gives food for thought on LINQ and the whole OR-mapping issue.

Saturday, January 14, 2006 10:13:48 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
LINQ | WPF
About
This blog is run by Mark Blomsma.
© Copyright 2009
Develop-One
Sign In
Statistics
Total Posts: 376
This Year: 34
This Month: 0
This Week: 1
Comments: 119
All Content © 2009, Develop-One
DasBlog theme 'Business' created by Christoph De Baene (delarou)