fluent-nhibernate /src/FluentNHibernate/Mapping/AnyPart.cs

Language C# Lines 175
MD5 Hash 7c71b8fc7ad2b42f4c3b4909a4c557dc
Repository https://github.com/dotnetchris/fluent-nhibernate.git View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using FluentNHibernate.Mapping.Providers;
using FluentNHibernate.MappingModel;
using FluentNHibernate.Utils;

namespace FluentNHibernate.Mapping
{
    /// <summary>
    /// Represents the "Any" mapping in NHibernate. It is impossible to specify a foreign key constraint for this kind of association. For more information
    /// please reference chapter 5.2.4 in the NHibernate online documentation
    /// </summary>
    public class AnyPart<T> : IAnyMappingProvider
    {
        private readonly AttributeStore<AnyMapping> attributes = new AttributeStore<AnyMapping>();
        private readonly Type entity;
        private readonly Member property;
        private readonly AccessStrategyBuilder<AnyPart<T>> access;
        private readonly CascadeExpression<AnyPart<T>> cascade;
        private readonly IList<string> typeColumns = new List<string>();
        private readonly IList<string> identifierColumns = new List<string>();
        private readonly IList<MetaValueMapping> metaValues = new List<MetaValueMapping>();
        private bool nextBool = true;

        public AnyPart(Type entity, Member property)
        {
            this.entity = entity;
            this.property = property;
            access = new AccessStrategyBuilder<AnyPart<T>>(this, value => attributes.Set(x => x.Access, value));
            cascade = new CascadeExpression<AnyPart<T>>(this, value => attributes.Set(x => x.Cascade, value));
        }

        /// <summary>
        /// Defines how NHibernate will access the object for persisting/hydrating (Defaults to Property)
        /// </summary>
        public AccessStrategyBuilder<AnyPart<T>> Access
        {
            get { return access; }
        }

        /// <summary>
        /// Cascade style (Defaults to none)
        /// </summary>
        public CascadeExpression<AnyPart<T>> Cascade
        {
            get { return cascade; }
        }

        public AnyPart<T> IdentityType(Expression<Func<T, object>> expression)
        {
            return IdentityType(ReflectionHelper.GetProperty(expression).ToMember().PropertyType);
        }

        public AnyPart<T> IdentityType<TIdentity>()
        {
            return IdentityType(typeof(TIdentity));
        }

        public AnyPart<T> IdentityType(Type type)
        {
            attributes.Set(x => x.IdType, type.AssemblyQualifiedName);
            return this;
        }

        public AnyPart<T> EntityTypeColumn(string columnName)
        {
            typeColumns.Add(columnName);
            return this;
        }

        public AnyPart<T> EntityIdentifierColumn(string columnName)
        {
            identifierColumns.Add(columnName);
            return this;
        }

        public AnyPart<T> AddMetaValue<TModel>(string valueMap)
        {
            metaValues.Add(new MetaValueMapping
            {
                Class = new TypeReference(typeof(TModel)),
                Value = valueMap,
                ContainingEntityType = entity
            });
            return this;
        }

        public AnyPart<T> Insert()
        {
            attributes.Set(x => x.Insert, nextBool);
            nextBool = true;
            return this;
        }

        public AnyPart<T> Update()
        {
            attributes.Set(x => x.Update, nextBool);
            nextBool = true;
            return this;
        }

        public AnyPart<T> ReadOnly()
        {
            attributes.Set(x => x.Insert, !nextBool);
            attributes.Set(x => x.Update, !nextBool);
            nextBool = true;
            return this;
        }

        public AnyPart<T> LazyLoad()
        {
            attributes.Set(x => x.Lazy, nextBool);
            nextBool = true;
            return this;
        }

        public AnyPart<T> OptimisticLock()
        {
            attributes.Set(x => x.OptimisticLock, nextBool);
            nextBool = true;
            return this;
        }

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        public AnyPart<T> Not
        {
            get
            {
                nextBool = !nextBool;
                return this;
            }
        }

        AnyMapping IAnyMappingProvider.GetAnyMapping()
        {
            var mapping = new AnyMapping(attributes.CloneInner());

            if (typeColumns.Count() == 0)
                throw new InvalidOperationException("<any> mapping is not valid without specifying an Entity Type Column");
            if (identifierColumns.Count() == 0)
                throw new InvalidOperationException("<any> mapping is not valid without specifying an Entity Identifier Column");
            if (!mapping.IsSpecified("IdType"))
                throw new InvalidOperationException("<any> mapping is not valid without specifying an IdType");

            mapping.ContainingEntityType = entity;

            if (!mapping.IsSpecified("Name"))
                mapping.Name = property.Name;

            if (!mapping.IsSpecified("MetaType"))
            {
                if (metaValues.Count() > 0)
                {
                    metaValues.Each(mapping.AddMetaValue);
                    mapping.MetaType = new TypeReference(typeof(string));
                }
                else
                    mapping.MetaType = new TypeReference(property.PropertyType);
            }

            foreach (var column in typeColumns)
                mapping.AddTypeColumn(new ColumnMapping { Name = column });

            foreach (var column in identifierColumns)
                mapping.AddIdentifierColumn(new ColumnMapping { Name = column });

            return mapping;
        }
    }
}
Back to Top