DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
TypeMappingConfiguration.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq.Expressions;
4 using System.Reflection;
5 
6 namespace Deveel.Data.Mapping {
7  public class TypeMappingConfiguration<T> : ITypeMappingConfiguration where T : class {
8  private Dictionary<string, IMemberMappingConfiguration> memberMappings;
9  private List<string> ignoredMembers;
10 
12  TableName = DiscoverTableName();
13  memberMappings = DiscoverMembers();
14  }
15 
16  private string TableName { get; set; }
17 
18  private string UniqueKeyMember { get; set; }
19 
21  get { return typeof (T); }
22  }
23 
25  get { return TableName; }
26  }
27 
29  get { return UniqueKeyMember; }
30  }
31 
32  IEnumerable<KeyValuePair<string, IMemberMappingConfiguration>> ITypeMappingConfiguration.Members {
33  get { return memberMappings; }
34  }
35 
36  private Dictionary<string, IMemberMappingConfiguration> DiscoverMembers() {
37  var dictionary = new Dictionary<string, IMemberMappingConfiguration>();
38 
39  var members = typeof (T).FindMembers(MemberTypes.Field | MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public, null, null);
40  foreach (var memberInfo in members) {
41  if (!Attribute.IsDefined(memberInfo, typeof (IgnoreAttribute), false)) {
42  dictionary[memberInfo.Name] = new MemberMappingConfiguration<T>(this, memberInfo);
43  } else {
44  Ignore(memberInfo.Name);
45  }
46  }
47 
48  return dictionary;
49  }
50 
51  private string DiscoverTableName() {
52  var tableNameAttr = Attribute.GetCustomAttribute(typeof(T), typeof(TableAttribute), false)
53  as TableAttribute;
54  if (tableNameAttr == null)
55  return null;
56  return tableNameAttr.TableName;
57  }
58 
59  private MemberInfo GetMemberInfo<TProperty>(Expression<Func<T, TProperty>> memberSelector) {
60  var type = typeof(T);
61 
62  var member = memberSelector.Body as MemberExpression;
63  if (member == null)
64  throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", memberSelector));
65 
66  var memberInfo = member.Member;
67  if (memberInfo == null)
68  throw new ArgumentException(string.Format("Expression '{0}' not refers to a field or a property.", memberSelector));
69 
70  if (type != memberInfo.ReflectedType &&
71  !type.IsSubclassOf(memberInfo.ReflectedType))
72  throw new ArgumentException(string.Format("Expresion '{0}' refers to a member that is not from type {1}.", memberSelector, type));
73 
74  return memberInfo;
75  }
76 
77  public TypeMappingConfiguration<T> ToTable(string name) {
78  TableName = name;
79  return this;
80  }
81 
82  public TypeMappingConfiguration<T> HasUniqueKey<TMember>(Expression<Func<T, TMember>> member) {
83  if (!String.IsNullOrEmpty(UniqueKeyMember))
84  throw new InvalidOperationException("A unique key member is already configured.");
85 
86  var memberInfo = GetMemberInfo(member);
87  UniqueKeyMember = memberInfo.Name;
88  return this;
89  }
90 
91  public MemberMappingConfiguration<T> Member<TMember>(Expression<Func<T, TMember>> member) {
92  var memberInfo = GetMemberInfo(member);
93  var memberName = memberInfo.Name;
94 
95  if (ignoredMembers != null &&
96  ignoredMembers.Contains(memberName))
97  throw new InvalidOperationException(String.Format("Member '{0}' is ignored and cannot be configured.", memberName));
98 
99  IMemberMappingConfiguration configuration;
100  if (!memberMappings.TryGetValue(memberName, out configuration)) {
101  configuration = new MemberMappingConfiguration<T>(this, memberInfo);
102  memberMappings[memberName] = configuration;
103  }
104 
105  return (MemberMappingConfiguration<T>) configuration;
106  }
107 
108  public void Ignore<TMember>(Expression<Func<T, TMember>> member) {
109  var memberInfo = GetMemberInfo(member);
110  var memberName = memberInfo.Name;
111 
112  Ignore(memberName);
113  }
114 
115  internal void Ignore(string memberName) {
116  if (ignoredMembers == null)
117  ignoredMembers = new List<string>();
118 
119  if (!ignoredMembers.Contains(memberName))
120  ignoredMembers.Add(memberName);
121  }
122  }
123 }
TypeMappingConfiguration< T > ToTable(string name)
IEnumerable< KeyValuePair< string, IMemberMappingConfiguration > > Members
Dictionary< string, IMemberMappingConfiguration > DiscoverMembers()
Dictionary< string, IMemberMappingConfiguration > memberMappings