예제 #1
0
        /// <summary>
        /// 通过托管属性及其对应的实体类型,并通过可用的缓存列表,查找对应的 DbTable。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="propertyOwner"></param>
        /// <param name="tablesCache"></param>
        /// <returns></returns>
        internal static RdbTable GetPropertyTable(IManagedProperty property, Type propertyOwner, Dictionary <Type, RdbTable> tablesCache)
        {
            RdbTable result = null;

            if (propertyOwner == null)
            {
                propertyOwner = property.OwnerType;
            }

            if (!tablesCache.TryGetValue(propertyOwner, out result))
            {
                if (!propertyOwner.IsAbstract)
                {
                    result = RdbTableFinder.TableFor(propertyOwner);
                }

                if (result == null)
                {
                    ORMHelper.ThrowBasePropertyNotMappedException(property.Name, propertyOwner);
                }

                tablesCache.Add(propertyOwner, result);
            }

            return(result);
        }
예제 #2
0
        protected override void UpdateRedundancy(Entity entity, ConcreteProperty redundancy, object newValue, IList <ConcreteProperty> refPathes, object lastRefId)
        {
            /*********************** 代码块解释 *********************************
             *
             * 假定场景是:
             * refPathes: D(CRef,AName) -> C(BRef) -> B(ARef),
             * lastRefId: AId。(B.ARef 是最后一个引用属性)
             * 则对应生成的 SQL 是:
             * update D set AName = @AName where CId in (
             *     select id from C where BId in (
             *          select id from B where AId = @AId
             *     )
             * )
             * 如果 B、C 表也有冗余属性,对应的 SQL 则是:
             * update B Set AName = @AName where AId = @BId
             * update C set AName = @AName where BId in (
             *     select id from B where AId = @AId
             * )
             *
             **********************************************************************/

            //准备所有用到的 DbTable
            var table     = RdbTableFinder.TableFor(redundancy.Owner);
            var refTables = new RefPropertyTable[refPathes.Count];

            for (int i = 0, c = refPathes.Count; i < c; i++)
            {
                var refProperty = refPathes[i];
                var refTable    = RdbTableFinder.TableFor(refProperty.Owner);
                if (refTable == null)
                {
                    ORMHelper.ThrowBasePropertyNotMappedException(refProperty.Name, refProperty.Owner);
                }

                refTables[i] = new RefPropertyTable
                {
                    RefProperty = refProperty,
                    OwnerTable  = refTable
                };
            }

            var sql = new ConditionalSql();

            //SQL: UPDATE D SET AName = {0} WHERE
            sql.Append("UPDATE ").AppendQuoteName(table)
            .Append(" SET ").AppendQuote(table, table.Translate(redundancy.Property))
            .Append(" = ").AppendParameter(newValue).Append(" WHERE ");

            int quoteNeeded = 0;

            if (refTables.Length > 1)
            {
                //中间的都生成 Where XX in
                var inWherePathes = refTables.Take(refTables.Length - 1).ToArray();
                for (int i = 0; i < inWherePathes.Length; i++)
                {
                    var inRef = inWherePathes[i];

                    //SQL: CId In (
                    sql.AppendQuote(table, inRef.OwnerTable.Translate(inRef.RefProperty.Property))
                    .Append(" IN (").AppendLine();
                    quoteNeeded++;

                    var nextRef = refTables[i + 1];

                    //SQL: SELECT Id FROM C WHERE
                    var nextRefOwnerTable = nextRef.OwnerTable;
                    sql.Append(" SELECT ").AppendQuote(nextRefOwnerTable, nextRefOwnerTable.PKColumn.Name)
                    .Append(" FROM ").AppendQuoteName(nextRefOwnerTable)
                    .Append(" WHERE ");
                }
            }

            //最后一个,生成SQL: BId = {1}
            var lastRef = refTables[refTables.Length - 1];

            sql.AppendQuote(table, lastRef.OwnerTable.Translate(lastRef.RefProperty.Property))
            .Append(" = ").AppendParameter(lastRefId);

            while (quoteNeeded > 0)
            {
                sql.AppendLine(")");
                quoteNeeded--;
            }

            //执行最终的 SQL 语句
            using (var dba = _dataProvider.CreateDbAccesser())
            {
                dba.ExecuteText(sql, sql.Parameters);
            }
        }