In my last post, I said I'd write the sample in C# to compare to F#. Well, I grossly underestimated the power of query comprehensions. The C# version is almost the same length (formatting differences, mainly). I'm surprised and impressed. (Or maybe I'm writing F# like I'd write C#.) Edit: I think maybe sequence expressions could cut it down a bit...
...But... C# still can't do discriminated unions efficiently or effectively ;).
1 // crudcreatecompare.cs: Generates LINQ CRUD table fields using the horribly named DatabaseBase code
2 //
3 // Tables look like: [Table(Name="dbo.Accounts")]
4 // Columns look like this:
5 // [Column(Storage="_AccountName", DbType="VarChar(128) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
6 // [DataMember(Order=1)] // Exists if serialization is turned on; used to order key parameters
7 // Emits:
8 // public static readonly TableHelper<Account, String> Accounts =
9 // CreateTable(dc => dc.Accounts, a => a.AccountName);
10
11 using System;
12 using System.Collections.Generic;
13 using System.Data.Linq.Mapping;
14 using System.IO;
15 using System.Linq;
16 using System.Reflection;
17 using System.Runtime.Serialization;
18
19 class Program
20 {
21 static void Main()
22 {
23 Console.WriteLine(
24 new Program().generate(
25 "C:\\yourlinq.dll"));
26 }
27
28 string generate(string asmpath)
29 {
30 var asm = Assembly.LoadFrom(asmpath);
31 var lines = from t in asm.GetExportedTypes()
32 let ta = getAttr<TableAttribute>(t)
33 where ta != null
34 let name = pluralize(ta.Name.Replace("dbo.", ""))
35 orderby name
36 select genTable(t, name);
37 return joinStrings("", lines);
38 }
39
40 string genTable(Type t, string tableName)
41 {
42 var keyProps =
43 from p in t.GetProperties()
44 let c = getAttr<ColumnAttribute>(p)
45 where c != null && c.IsPrimaryKey
46 let dm = getAttr<DataMemberAttribute>(p)
47 orderby dm == null ? 0 : dm.Order
48 select p;
49 var tw = new StringWriter();
50 tw.WriteLine("public static readonly TableHelper<{0}, {1}> {2} =",
51 t.Name,
52 joinStrings(", ", keyProps.Select(p => p.PropertyType.Name)),
53 tableName);
54 tw.WriteLine("\tCreateTable(dc => dc.{0}, {1});",
55 tableName,
56 joinStrings(", ", keyProps.Select(p => "a => a." + p.Name)));
57 tw.WriteLine();
58 return tw.ToString();
59 }
60
61 string joinStrings(string sep, IEnumerable<string> items)
62 {
63 return string.Join(sep, items.ToArray());
64 }
65 string pluralize(string s)
66 {
67 return s.EndsWith("s") ? s : s + "s";
68 }
69
70 T getAttr<T>(ICustomAttributeProvider icap)
71 {
72 var a = icap.GetCustomAttributes(typeof(T), true);
73 return a.Length == 0 ? default(T) : (T)a[0];
74 }
75 }
Remember Me