| James's profileJames McCaffreyBlogLists | Help |
|
March 27 The ADO.NET Entity Framework and Error 2048The ADO.NET Entity Framework (AEF) v1.0 is part of Visual Studio 2008 SP1. The AEF examines a SQL database and creates wrapping C# code that can be used in an application to perform insert, update, create, and delete operations on the database. Yesterday I ran into an interesting error and an interesting solution. I created a dbCars DB with two tables, tblMakes ("Audi", "BMW", etc.) and tblModels ("A4", "328i", etc.) The tblModels table has a foreign key make_id into tblMakes, with an FK constraint named fk_tblModels_tblMakes. In AEF v1.0 if you want to use any stored procedures with a table, you must implement all three of insert, update, and delete procs. Anyway, after doing this and compiling a C# console application I got: Error "2048: The EntitySet 'tblModels' includes function mappings for AssociationSet 'fk_tblModels_tblMakes', but none exists in element 'DeleteFunction' for type 'dbCarsModel.tblModels'. AssociationSets must be consistently mapped for all operations." I beat my head on this for a while but a couple of guys on the AEF team, Daniel and Michael, explained. Basically, the FK constraint referred to keys in both tblMakes and tblModels but my usp_DeleteModel only uses the model key as an input parameter. One solution is to recast the usp_DeleteModel to accept a dummy input parameter of the make_id. That worked but just didn't feel quite right. A second solution is to open the Model1.edmx file with an XML editor and place this mapping code into the SSDL section:
<Function Name="Custom_DeleteModel" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" >
<CommandText> EXECUTE dbcars.usp_DeleteModel @model_id </CommandText> <Parameter Name="make_id" Type="char" Mode="In" /> <Parameter Name="model_id" Type="int" Mode="In" /> </Function> Then, after going back to the visual designer view of the .edmx file I remapped the DeleteFunction entry to the newly defined Custom_DeleteModel (which automatically appeared in the GUI dropdown control). The XML mapping code above has the dummy make_id parameter which keeps the compiler happy, and calls the usp_DeleteModel stored procedure using just the natural model_id parameter. Cool. Here are the particulars:
create database dbCars
go use dbCars
go create table tblMakes -- 'Audi', 'BMW', etc.
( make_id nchar(3) primary key, make_name nvarchar(25) not null, make_country nchar(2) null, ) go create table tblModels -- 'A4', '325i', etc.
( model_id int primary key, make_id nchar(3), -- foreign key model_name nvarchar(25) not null, model_type nvarchar(25) null -- 'SUV', '2-door coupe', etc. ) go alter table tblModels add constraint fk_tblModels_tblMakes foreign key(make_id) references tblMakes(make_id) go -- create procedure usp_InsertMake (here)
-- create procedure usp_InsertModel (here) -- create procedure usp_UpdateMake (here) -- create procedure usp_UpdateModel (here) create procedure usp_DeleteMake
@make_id nchar(3) as -- delete all associated Models first delete from tblModels where tblModels.make_id = @make_id -- now can delete the Make delete from tblMakes where make_id = @make_id go create procedure usp_DeleteModel
@model_id int as delete from tblModels where model_id = @model_id go Like many v1.0 products the AEF has its glitches but I bet that this one at least will be fixed with v2.0 which I think will ship with .NET Framework 4.0 and Visual Studio 2010. March 20 Symmetric Test Case InputI ran across an interesting testing situation the other day. I was looking at a library module for 7-card poker which contains a method int Hand.Compare(Hand h1, Hand h2) to determine which of two 7-card poker hands is better according to the rules of poker. This is a surprisingly tricky method to code up and I use it for many different types of software testing investigations. Anyway, consider these two poker hands:
h1 = Ac Ad Ah 9s 9c 9d 2c
h2 = Kc Kd Ks Jc Jd Js Qh The first hand is a full house Aces over Nines (usually pronounced Aces full of Nines). The second hand is a full house Kings over Jacks. A call to Hand.Compare(h1, h2) should return -1 because h1 is better than h2. OK, but if you execute this test case should you also execute Hand.Compare(h2, h1) with an expected result of +1? The answer is yes, absolutely. Well this is basically testing 101 information but it got me to thinking about situations where you absolutely need to create symmetric test case input. I didn't come up with any remarkable epiphanies but it did remind me that there are a few testing principles, like you should almost always create test cases with symmetric input, that are easy to overlook.
March 13 Simulated Bee Colony AlgorithmsI've always been fascinated by algorithms which are inspired by natural processes. In fact my Master's thesis investigated optimization using genetic algorithms which mimic evolutionary processes by simulating genetic crossover and mutation. During the past few months I've been looking at optimization algorithms which are based on the behavior of honey bee colonies. These types of algorithms have been studied since at least 1997 and perhaps earlier, but have received a lot of attention in the past three years. Different researchers use different approaches and end up with slightly different meta-heuristics. Some of the names I've come across in my research include Bee System, BeeHive, Virtual Bee Algorithm, Bee Swarm Optimization, Bee Colony Optimization, Artificial Bee Colony, and Bees Algorithm. The basic idea is that foraging bees have a potential solution to an optimization problem in their memory. This solution corresponds to the location of a food source. Each food source has an associated quality measure of how well it solves the optimization problem. Foraging bees return to the hive and perform a waggle dance which describes a potential solution and it quality to currently inactive foragers. These inactive bees then go to the food source and examine nearby sources/solutions. There are also scout foragers who randomly search the problem domain space. Anyway, I cooked up a program which uses a simulated bee colony algorithm to solve various problems in software testing and the results were very promising. I've written up a paper and intend to submit it to a software conference at some point. March 08 Testing with F#F# is Microsoft's new programming language. F# is scheduled to ship with the next version of Visual Studio but a Community Technical Preview version is available. F# is a functional language which means among other things that most language constructs are related to functions and return values. I've had quite a bit of experience with Prolog and LISP, two old functional languages and I never really liked them very much. But I've been looking at F# and like what I've seen so far. For test automation, one traditional, non-functional approach is to create test case data and then iterate through the data. Here is a snippet of what this might look like with F#:
let testCases =
[ "001,3,5,8" "002,0,0,0" "003,2,4,6" ] let dummy = Seq.iter(fun(testCase) -> let delimits = [|',';'~'|]; let tokens = testCase.Split(delimits) let caseID = tokens.[0] let input1 = tokens.[1] let input2 = tokens.[2] let expected = tokens.[3] // send input1 & input2 to SUT // check actual return with expected if actual == expected then printfn "Pass" else printfn "Fail" true ) The first part of the snippet sets up an F# List object of test case input. The second part of the snippet uses Seq.iter (sequence iterator) to process each item in the List by applying an anonymous function (indicated by the "fun" keyword) which always returns true. Like anything else, it takes a while to get up to speed with F# but so far it's been an interesting investigation.
|
|
|