예제 #1
0
        public static System.Linq.IQueryable <TEntity> Contains <TEntity, T>(this System.Linq.IQueryable <TEntity> source,
                                                                             IEnumerable <T> forCollection, string fullyQualifiedTableName, bool avoidReadLocks = false,
                                                                             params Expression <Func <TEntity, object> >[] joinColumns
                                                                             )
            where TEntity : class

        {
            var root = new XElement("nodes");

            //generate xml
            foreach (var entity in forCollection)
            {
                root.Add(new XElement("node",
                                      joinColumns.Select(c => new XElement(ExtensionHelper.GetProperty(c).Name,
                                                                           entity.GetType().GetProperty(ExtensionHelper.GetProperty(c).Name)?.GetValue(entity, null)))));
            }

            var sqlStr =
                new StringBuilder(
                    $"SELECT tbl.* FROM @xml.nodes('/nodes/node') nodes([node]) JOIN {fullyQualifiedTableName} tbl {(avoidReadLocks ? "WITH (NOLOCK)" : "")} ON ");

            //append join filter clauses
            sqlStr.Append(string.Join(" AND ",
                                      joinColumns.Select(c =>
                                                         $"tbl.[{ExtensionHelper.GetProperty(c).Name}] = [nodes].[node].value('({ExtensionHelper.GetProperty(c).Name})[1]', '{ExtensionHelper.GetDbMappedType(ExtensionHelper.GetProperty(c).GetUnderlyingType())}')")));

            var matched = source.FromSql(sqlStr.ToString(), new SqlParameter("@xml", new SqlXml(root.CreateReader())));

            return(matched.AsQueryable());
        }