個人檔案Blogs部落格清單 工具 說明

部落格


3月3日

Contains with the Entity Framework.

Sometimes you need to get a result set for a field that contains any value from an array.
The default approach in LINQ would be:

from var c in data where array.Contains(c.field) select c;

which creates a T-SQL that looks like that:

select * from data where data.field in (1,2,3,...)

Unfortunately, this would produce an error with EF, since Contains is currently not implemented with .NET 3.5SP1.

Therefore, we need a workarround that builds an expression that implements an or for each indiviudal value in the array to be compared against the field:

private void button2_Click(object sender, RoutedEventArgs e)
{
    int[] types = new int[] { 1, 2, 3, 10 };
    using (TomsPortal.TomsPortalEntities1 tp = new TomsPortalEntities1())
    {
        var r = from node in tp.Node where node.Taxonomy.Id != 3 where Contains<Node, int>(types) select node;
        r = r.Where(Contains<Node, int>(node => node.Id, types));

        foreach (var o in r)
        {
            Trace.WriteLine(o.Id);
        }
    }
}

static Expression<Func<TElement, bool>> Contains<TElement, TValue>(this Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
    if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); }
    if (null == values) { throw new ArgumentNullException("values"); }
    if (!values.Any()) return e => false;

    var
equals = from value in values
        select
            System.Linq.Expressions.Expression.Equal(
                valueSelector.Body,
                System.Linq.Expressions.
Expression.Constant(value, typeof(TValue))
            );

    var
body = equals.Aggregate((accumulate, equal) =>
        System.Linq.Expressions.Expression.Or(accumulate, equal));

    ParameterExpression
p = valueSelector.Parameters.Single();
    var ex = System.Linq.Expressions.Expression.Lambda<Func<TElement, bool>>(body, p);
   
    return
ex;
}

Intersection with Linq2SQL

 
Imagine you have a data table that is specified as followed:
 
 
CREATE TABLE MyTable
  ArticleId int NOT NULL,
  CategoryId int NOT NULL
 
 
and you want to return all article ids that interesect with an array of Category Id's using LINQ2SQL.
 
Here is a solution:
 
int[] categoryIds = new int[] {29,5201,4};
IQueryable<ObjectNodeView> result = context.MyTable;

// make a select for the first category:
int firstCategory = categoryIds.First();
result = from a in result where a.CategoryId == firstCategory select a;

// now intersect all other categories using a inner join:
foreach(int categoryId in categoryIds.Skip(1))
{
   result = from a in result
      join a2 in context.MyTable on a.ArticleId equals a2.ArticleId 
     where a2.CategoryId == categoryId
     select a;
}
9月8日

WPF BreadcrumbBar

A windows vista like breadcrumb bar for wpf that supports any kind of hierarchical datasource, HierarchicalDataTemplate, dynamic population, command buttons, dropdown list, a progressbar inside and many more.
 
The BreadcrumbBar is part of the new Odyssey assembly that I'm currently developing which will contain various neat controls, introducing the breadcrumb bar.
 
You're welcome to use the BreadcrumbBar for your own applications without paying any charge. The source code with two example appications is available on popfly:
 
 
The included examples show how to populate the breadcrumb bar on demand and conversion from edit path to display path and vice versa by implementing a folder browser, the other examples shows how to use the breadcrumb bar with an XmlDataSource without writing any custom code.
 
Feel free to use it!
 
 
 
7月28日

Performance of LINQ

Curious of how fast LINQ would be to filter items from a large list, I was writing a test In Visual Studio 2008 Beta 2 to determine the performance, by creating a List of a class that contains 1 million items to be filtered and sorted:

        
        // Performing a LINQ command for a list of 100.000 items:
        public IEnumerable<item> Filter(IList<item> list) 
        { 
            IEnumerable<item> items =
                from it
in list where it.value < 40 || it.text.StartsWith("W")
                orderby it.text select it; 

            return items; 
        } 

                // Create a list of 1,000,000 items with random value:    
        private void button2_Click(object sender, RoutedEventArgs e) 
        { 
            List<item> items = new List<item>(); 
            Random r = new Random(); 
            Random m =new Random(); 
           
for (int i = 0; i < 1000000; i++) 
            { 
                StringBuilder sb  = new StringBuilder(); 
                for (int x=0;x<10;x++) 
                { 
    
                    char c = (char)(m.Next(27)+65); 
                    sb.Append(c); 
                } 
                item item = new item(); 
                item.text = sb.ToString(); 
                item.value = r.Next(100000); 
                items.Add(item); 
            } 
   
            int t1 = Environment.TickCount; 
    
            IEnumerable<item> filtered = Filter(items); 
    
    
            bool stopped = false;
            foreach
(item it in filtered) 
            { 
              if (!stopped)
              {
                int t2 = Environment.TickCount; 
                Trace.Write("Duration: "); 
                Trace.WriteLine(t2 - t1);
                stopped = true;
              }

                Trace.Write(it.value); 
                Trace.Write(" "); 
                Trace.WriteLine(it.text); 
            } 
    
        } 
    } 
    
    public class item 
    { 
        public int value; 
        public string text; 
    } 
 

To filter 1,000,000 items, it took only 631ms on a @2400GHz Core 2 Duo that was even virtualized with Virtual PC!
That's very impressive!


Note, that the LINQ result IEnumerable<item> does NOT immediately perform to filter but after the first item is request, so that explains the weired code and why I was using the stopped variable.

 

4月17日

Vista Complete PC Restore

Note: The vista complete pc restore is a functionality which is present on windows vista ultimate and windows vista business but not home premium or home basic

Today, when I came home from work, I had a unpleasant surprise when I was synchronizing my laptop with my pc:
At the tray, I noticed a new tray icon, so I clicked on it to find out what it is for. It opened a dialog that informed me that my Intel Raid 0 with 2 hd has detected an error on one disk and I should perform a complete backup asap. I'm using 2x250 hds and although I got a usb hd for backup purpose, this backup disk would never fit the required size. So I removed all temporary files and deleted all restore points except the latest to make size. From 260 gb of used bytes I could shrink it to 180 gb! Nice work, but still to much for my 80 gb backup drive. So I decided to abuse my windows xp computer with a 2x80 raid 0 system which I only use occasionally for windows xp testings and plugged them onto my vista computer and made my first complete backup. Other than a standard backup, the complete backup does not compress the files, so the size is indeed the same as the hd requires. It creates a *.vhd file that possibly can be used on a virtual machine like virtual pc 2007.

Now I could spend my time to attempt to solve the disk problem. What I did was simply delete the raid and recreate it again. Unfortunately, this also caused the contents of the raid getting lost, but no problem I got a backup! I restarted my pc with my windows vista ultimate dvd and instead of installing I selected the restore option, loaded the drivers for the backup raid (which was not an intel driver) from a usb stick that I've loaded from the internet with my laptop, and it detected the backup. Currently the computer is still restoring.

Finally, I got to say that this functionality is a very nice feature, because it saved me lots of time reinstalling vista and all applications again, which would take at least one day, maybe too.

4月16日

Sliverlight

Microsoft Silverlight is a new cross platform multimedia streaming client that will make the adobe flash player obsolete.

You can get more details about silverlight at the following web site:

 

http://www.microsoft.com/silverlight/default_01.aspx

4月14日

Code snippet

Here is a code example for an application that converts toolbar images by size and compression. I pulish this application for the sake of offering hints and ideas of how to develop software with .NET 2.0.
 
Interesting might be the IsImage() method where I check if a file name has an extension of an image. Instead of checking each possible extension separately I use a loop and a string[] collection that is initialized staticly which makes this method easy to read, small in code and easily to extend.
 
Also interesting might be how to implement drag & drop functionality to an application and read the items that where dropped on it, eq. from the windows explorer.
 
Now here comes the code:
 

SourceImage.cs

 

namespace ImageConverter
{     public class SourceImage
    { 
        public SourceImage(string path) 
            : base() 
        { 
            this.path = path; 
        } 
  
        internal string path; 
  
        public string Path { get { return path; } } 
        public string Name 
        { 
            get 
            { 
                return System.IO.Path.GetFileNameWithoutExtension(path); 
            } 
        } 
  
        internal string RenameExt(string extension) 
        { 
            string ext = System.IO.Path.GetExtension(this.path); 
            string name = Name;
             { 
                name = name + "_copy"
            } 
  
            string path = System.IO.Path.GetDirectoryName(this.path); 
            path = System.IO.Path.Combine(path, name) + extension; 
            return path; 
        } 
    }

  
    public class SourceImageList : List<SourceImage
    { 
        public SourceImage Add(string path) 
        { 
            SourceImage image = new SourceImage(path); 
            Add(image); 
            return image; 
        } 
    }
 

ImageFormats.cs

 

namespace ImageConverter

    public sealed class ImageFormatInfo 
    { 
        public ImageFormatInfo(ImageFormat format, string extension, string description) 
            : base() 
        { 
            this.format = format; 
            this.description = description; 
            this.extension = extension; 
        } 
  
        private string extension; 
        private string description; 
        private ImageFormat format; 
  
        public string Extension { get { return extension; } } 
        public string Description { get { return description; } } 
        public ImageFormat Format { get { return format; } } 
    } 
  
    public sealed class ImageFormatList : List<ImageFormatInfo
    { 
        public ImageFormatList() 
            : base() 
        { 
            Add(ImageFormat.Bmp, ".bmp", "Bitmap"); 
            Add(ImageFormat.Jpeg, ".jpg", "Jpeg"); 
            Add(ImageFormat.Gif, ".gif", "Gif"); 
            Add(ImageFormat.Png, ".png", "Png"); 
        } 
  
        private void Add(ImageFormat format, string extension, string description) 
        { 
            Add(new ImageFormatInfo(format, extension, description)); 
        } 
    }
}

 

Form1.cs:

 

namespace ImageConverter

    { 
        Size imageSize = new Size(16, 16); 
        private Color imageBackground = Color.Fuchsia; 
  
        public Form1() 
        { 
            InitializeComponent(); 
            ImageBackGround = Color.Fuchsia; 
            cbTarget.DataSource = formats; 
        } 
  
        private ImageFormatList formats = new ImageFormatList(); 
        private SourceImageList sources = new SourceImageList(); 
  
        public Color ImageBackGround 
        { 
            get { return imageBackground; } 
            set 
            { 
                imageBackground = value
                tbColor.BackColor = value
            } 
        } 
  
        private void listView1_DragOver(object sender, DragEventArgs e) 
        { 
            e.Effect = e.AllowedEffect; 
        } 
  
        private void imageList_DragDrop(object sender, DragEventArgs e) 
        { 
            string[] images = (string[])e.Data.GetData(DataFormats.FileDrop, false); 
            foreach (string image in images) 
            { 
                if (IsImage(image)) 
                { 
                    SourceImage sourceImage = sources.Add(image); 
                    if (image!=null
                    { 
                        imageList.Items.Add(sourceImage.Name).Tag = sourceImage; 
                    } 
                } 
            } 
        } 
  
        private bool IsImage(string image) 
        { 
            string ext = System.IO.Path.GetExtension(image); 
            string[] extensions = { ".bmp", ".gif", ".jpg", ".jpeg", ".png" }; 
            foreach (string extension in extensions) 
            { 
                if (ext.Equals(extension, StringComparison.OrdinalIgnoreCase)) return true
            } 
            return false
        } 
  
        private void btConvert_Click(object sender, EventArgs e) 
        { 
            ImageFormatInfo format = cbTarget.SelectedItem as ImageFormatInfo
            foreach (SourceImage image in sources) 
            { 
                using (Bitmap targetBm = new Bitmap(imageSize.Width, imageSize.Height)) 
                { 
                    Graphics g = Graphics.FromImage(targetBm); 
                    g.Clear(imageBackground); 
                    using (Bitmap sourceBm = new Bitmap(image.Path)) 
                    { 
                        sourceBm.MakeTransparent(); 
                        int x = (imageSize.Width-sourceBm.Width)/2; 
                        int y = (imageSize.Height-sourceBm.Height)/2; 
                        g.DrawImageUnscaled(sourceBm, x, y); 
  
                        string fileName = image.RenameExt(format.Extension); 
                        targetBm.MakeTransparent(ImageBackGround); 
                        targetBm.Save(fileName, format.Format); 
                    } 
                } 
            } 
        } 
  
        private void button1_Click(object sender, EventArgs e) 
        { 
            colorDialog.Color = ImageBackGround; 
            if (colorDialog.ShowDialog() == DialogResult.OK) 
            { 
                ImageBackGround = colorDialog.Color; 
            } 
        } 
  
        private void btClear_Click(object sender, EventArgs e) 
        { 
            sources.Clear(); 
            imageList.Clear(); 
        } 
  
        private void numericUpDown1_ValueChanged(object sender, EventArgs e) 
        { 
            imageSize.Width = (int)((NumericUpDown)sender).Value; 
        } 
  
        private void numericUpDown2_ValueChanged(object sender, EventArgs e) 
        { 
            imageSize.Height = (int)((NumericUpDown)sender).Value; 
        } 
    }
}
 

 
 
 
4月13日

The Breadcrumb Bar

Since Windows Vista, you're familiar with this new kind of control. The breadcrumb bar was introduced with the windows explorer and replaces the combo box for the path. But the breadcrumb offers much more than only showing the path. It separates each sub folder as a breadcrumb so the user can go back with ease by just clicking the appropriate breadcrumb or selects another sibling of a breadcrumb which represents another folder inside a folder. The breadcrumb bar can also include some image buttons on the right and an icon on the left as well as a dropdown button that behaves like the dropdown button of a combo box. Even a progress bar is included in the breadcrumb bar!

You can use a breadcrumb bar not only for paths but also for other purposes. For instance in my profession I'm developing an application that shows the medical history of a patient. In the breadcrumb bar, I offer the name of the patient and also the available health insurance voucher of the patient, followed by its type, and the date separated by year, quarter or month, day that may look like this:

Miller, Max (2003-03-24) à Emergency à AOK Berlin à 2007 à November à 15

This is just one other example for what a breadcrumb bar can be used for, there are so many other possibilities. As I'm developing .NET applications, I wrote a breadcrumb bar as part of my jedi.dll assembly which also contains the previously mentioned JediGrid. Soon the jedi.dll will be available for free private use on www.tomssoftware.net, just be patient.

Here is a brief scheme of the breadcrumb bar:

4月1日

Does Ready Boost slow down your system?

There are certain rumors about this issue that claim that as soon as ready boost is installed, the cpu raises from 1% idle time to constantly 30-40%, like the following article:
 
 
  • how serious are these reports?
  • what is fact?

The truth is, the reports a right, but:

  • as soon as you install a new medium for ready boost, vista analyzes the system to determine what can be extended to the external medium. This analysis requires a view minutes and does indeed consume resources so that your computer can become unhandsome.
  • Also, when you reboot, this anayzing process starts when you log in, but
  • Vista is designed not to shut dow when you press the exit button, but rather going in standbye or sleep mode due to the fact that meanwhile all main boards and cards supports standbye and against common opinion that standbye consumes more power thant to shut down the computer, the truth is, that there is not difference in power consumption whether you are in sleep mode or you have indeed shut down your computer. Only when you switch the button on the back of your computer, it is really off.

 

So I come to the result, that ready boost does what it's supposed to do, to increase the performance of your computer as long as you use you're vista computer like it was designed to be used.

Rumors that claim to say the oposite are either mistaken because of the analyzis process, or just propaganda from tux landers.