tag:blogger.com,1999:blog-34049130.post4361131279821337544..comments2024-03-18T08:24:48.823+01:00Comments on The Tapir's Tale: TDD and LINQ to SQLAnders Janmyrhttp://www.blogger.com/profile/16081537018884349622noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-34049130.post-54140264693853874832008-10-31T06:52:00.000+01:002008-10-31T06:52:00.000+01:00Daniel: I finally got the time to check out your e...Daniel: I finally got the time to check out your example.<BR/><BR/>The InMemoryTables and the InMemoryUnitOfWork do not work like a full-fledged LinqToSql-replacement.<BR/>They are just meant to support my unit tests. The test that you have shown I would consider an integration test and it is not part of the case I'm trying to solve.<BR/><BR/>I am considering scaling the InMemory project to support what you are suggesting if I can only find the time.Anders Janmyrhttps://www.blogger.com/profile/01927713088132429031noreply@blogger.comtag:blogger.com,1999:blog-34049130.post-52949197969869990392008-10-28T20:07:00.000+01:002008-10-28T20:07:00.000+01:00Awesome. I've thought about this before, but assu...Awesome. I've thought about this before, but assumed some magic was happening in DataContext to wire up the relationships. Especially since EntitySet lives in System.Data.Linq. I just tried and indeed it's handling those for queries just fine. I'm still a little mystified, though - what's doing that work? In other words, how does the EntitySet of Round know where to find the related List of Round in InMemoryUnitOfWork?<BR/><BR/>Probably related - one test that's failing for me is inserting entity with related data:<BR/><BR/>var player = new Player() { ... }<BR/>var round = new Round() {... }<BR/>player.Rounds.Add(round);<BR/>context.InsertOnSubmit(player);<BR/>context.SubmitChanges();<BR/><BR/>Assert.IsTrue(context.Rounds.Count() == 1);<BR/><BR/>Fails for MemoryUnitOfWork, but succeeds for LinqToSql. Which I guess means my InsertOnSubmit/SubmitChanges isn't right. Thoughts?Daniel Roothttps://www.blogger.com/profile/04004685127300233374noreply@blogger.comtag:blogger.com,1999:blog-34049130.post-27524913641107369232008-10-28T08:05:00.000+01:002008-10-28T08:05:00.000+01:00Daniel: It works fine.The relationships are set up...Daniel: It works fine.<BR/><BR/>The relationships are set up in the entity classes with attributes or with an external mapping file just as you would if you were using the tables directly.<BR/><BR/>The <B>only</B> thing you gain is testability.<BR/><BR/>Here is an example of one of my queries:<BR/><BR/><BR/>public IEnumerable<TotalResult> CalculateTotalResults(IEnumerable<Round> playedRounds)<BR><BR/>{<BR><BR/> var totalResults = from round in playedRounds<BR><BR/> from result in round.GetCalculatedResults()<BR><BR/> group result by result.Player<BR><BR/> into playerResults<BR><BR/> select new TotalResult(playerResults.Key, playerResults);<BR><BR/><BR><BR/> var totalResultsSorted = from r in totalResults<BR><BR/> orderby r.GetTotal() descending<BR><BR/> select r;<BR><BR/> return totalResultsSorted;<BR><BR/>}<BR>Anders Janmyrhttps://www.blogger.com/profile/01927713088132429031noreply@blogger.comtag:blogger.com,1999:blog-34049130.post-36381274784526792922008-10-27T23:55:00.000+01:002008-10-27T23:55:00.000+01:00Does this really work with complex LINQ-to-SQL que...Does this really work with complex LINQ-to-SQL queries? If so, where are the relationships between tables handled? ie:<BR/><BR/>from r in Rounds<BR/>where r.Score < 100<BR/>select r.PlayerDaniel Roothttps://www.blogger.com/profile/04004685127300233374noreply@blogger.comtag:blogger.com,1999:blog-34049130.post-3715135920431282842008-10-27T08:59:00.000+01:002008-10-27T08:59:00.000+01:00wolfbyte: Good point! I'll update the code. I wil...wolfbyte: Good point! I'll update the code. I will also have to make InMemoryUnitOfWork hold a Dictionary with a mapping between class and table instead of instance variables for every table.Anders Janmyrhttps://www.blogger.com/profile/01927713088132429031noreply@blogger.comtag:blogger.com,1999:blog-34049130.post-45483164706592708852008-10-26T22:45:00.000+01:002008-10-26T22:45:00.000+01:00Nice work Anders.It's a little thing but the I...Nice work Anders.<BR/><BR/>It's a little thing but the IUnitOfWork interface that you have there kinda violates the Open/Closed Principle. Every time you add a domain object you're going to have to crack that open and provide yet another member on it. As you're using it as an abstraction, this means you'll have two other places (at least) to mess with it as well :(<BR/><BR/>Instead, why not duplicate what the DataContext was doing originally and expose a GetTable<T> which returns an ITable<T>. That way your InMemoryUnitOfWork and LinqToSqlUnitOfWork don't have to change no matter how many domain classes you create.<BR/><BR/>The only issue with this is that it hides the intent a little bit but given that (I assume) you won't be using the IUnitOfWork directly maybe that is ok.<BR/><BR/>At least that is what I've been doing. Just a thought.Wolfbytehttps://www.blogger.com/profile/14133583302150503315noreply@blogger.com