private void GetByArgsOnQuery(DatabaseParameters p, PersonArgs args, IDatabaseArgs dbArgs) { p.ParamWithWildcard(args?.FirstName, DbMapper.Default[nameof(Person.FirstName)]) .ParamWithWildcard(args?.LastName, DbMapper.Default[nameof(Person.LastName)]) .TableValuedParamWith(args?.Genders, "GenderIds", () => TableValuedParameter.Create(args.Genders.ToGuidIdList())); }
/// <summary> /// Gets the entities that should not be removed as part of an upgrade operation. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> public IEnumerable <Guid> GetDoNotRemove(IProcessingContext context) { // Namely, get the entities that: // 1. used to be part of the application, // 2. which are no longer part of the application, // 3. which are still present in the tenant (i.e. the app developer removed them from the app, but didn't delete them altogether). // 4. we also need to carry over any entities marked as 'do not remove' in previous versions // Step 0: Determine what the original version of this package was Guid?packageId = OriginalPackageId; if (packageId == null) { context.WriteInfo("Tenant application does not have a package Id"); return(Enumerable.Empty <Guid>( )); } // Step 1: Get entities in the previous version LibraryAppSource appLibrarySource = new LibraryAppSource { AppVerId = packageId.Value }; IEnumerable <Guid> entitiesInPrevVersion = appLibrarySource .GetEntities(context) .Select(e => e.EntityId) .ToList( ); // Step 2: Disregard entities that are still in the application IEnumerable <Guid> entitiesInTenantApp = ((IDataSource)this) .GetEntities(context) .Select(e => e.EntityId); IEnumerable <Guid> missingEntities = entitiesInPrevVersion.Except(entitiesInTenantApp).ToList(); // Step 3: Check database to see if the entities are still present ISet <Guid> doNotRemove = new HashSet <Guid>( ); DataTable dt = TableValuedParameter.Create(TableValuedParameterType.Guid); foreach (var guid in missingEntities) { dt.Rows.Add(guid); } using (IDbCommand command = CreateCommand( )) { command.CommandText = "dbo.spGetEntityIdsByUpgradeIds"; command.CommandType = CommandType.StoredProcedure; command.AddParameter("@tenantId", DbType.Int64, TenantId); command.AddTableValuedParameter("@data", dt); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { var guid = reader.GetGuid(0); doNotRemove.Add(guid); // entities still in the tenant should be marked as 'do not remove' } } } // Step 4: Include entities marked as 'do not remove' in previous tenants var carriedOver = appLibrarySource.GetDoNotRemove(context); foreach (Guid guid in carriedOver) { doNotRemove.Add(guid); } // Entities that have been removed from the application, but still present in the tenant, // should get marked as 'do not delete' to indicate that when the application is upgraded it should not delete the entities. return(doNotRemove); }
/// <summary> /// Sets the value. /// </summary> /// <param name="parameter">The parameter.</param> /// <param name="value">The value.</param> public void SetValue(IDbDataParameter parameter, object value) { TableValuedParameter.Set(parameter, value as DataTable, null); }
/// <summary> /// Gets the deletions. /// </summary> /// <param name="tableName">Name of the table.</param> /// <param name="tvpType">Type of the TVP.</param> /// <returns></returns> public DataTable GetDeletions(string tableName, TableValuedParameterType tvpType) { return(Get(tableName, Deletions, name => TableValuedParameter.Create(tvpType))); }
private void GetByArgsOnQuery(DatabaseParameters p, PersonArgs args, IDatabaseArgs dbArgs) { p.ParamWithWildcard(args?.FirstName, DbMapper.Default[Person.Property_FirstName]) .ParamWithWildcard(args?.LastName, DbMapper.Default[Person.Property_LastName]) .TableValuedParamWith(args?.Genders, "GenderCodes", () => TableValuedParameter.Create(args.Genders.ToCodeList())); }
/// <summary> /// Prepare the SQL to load in relationships of all applicable types, in one direction. /// </summary> private void ProcessRelationships(Direction relDirection) { // Creates a list of relationship transition rules, where each tuple contains (in order): // 1. the node that the relationship instruction applies to // 2. the relationship ID // 3. the node that the relationship points to var relRequests = from nodeInfo in _requestNodeMap.Values from relReq in nodeInfo.Request.Relationships where Entity.GetDirection(relReq.RelationshipTypeId, relReq.IsReverse) == relDirection select new { NodeInfo = nodeInfo, RelRequest = relReq }; var dt = TableValuedParameter.Create(TableValuedParameterType.BulkRelType); //var relMap = new List<Tuple<int, long, int>>( ); var map = new HashSet <Tuple <int, long, int> >( ); foreach (var relReqInfo in relRequests) { if (relReqInfo.RelRequest.MetadataOnly) { continue; // Don't load actual data } int nodeId = relReqInfo.NodeInfo.Tag; var relReq = relReqInfo.RelRequest; var mapRule = new Tuple <int, long, int>(nodeId, relReq.RelationshipTypeId.Id, _requestNodeMap [relReq.RequestedMembers].Tag); if (!map.Contains(mapRule)) { map.Add(mapRule); dt.Rows.Add(mapRule.Item1, mapRule.Item2, mapRule.Item3); } if (relReq.IsRecursive) { var recursiveRule = new Tuple <int, long, int>(nodeId, relReq.RelationshipTypeId.Id, nodeId); if (!map.Contains(recursiveRule)) { map.Add(recursiveRule); dt.Rows.Add(recursiveRule.Item1, recursiveRule.Item2, recursiveRule.Item3); } } } if (map.Count == 0) { return; } string tblName = relDirection == Direction.Forward ? "@relFwd" : "@relRev"; _result.TableValuedParameters [tblName] = dt; // Gather metadata for relationship requests var relReqs = from node in _request.WalkNodes( ) from relReq in node.Relationships select relReq; foreach (var relReq in relReqs) { var relTypeId = relReq.RelationshipTypeId.Id; var relEntity = Entity.Get <Relationship>(relTypeId); if (relEntity == null) { continue; } long key = relTypeId; var direction = Entity.GetDirection(relReq.RelationshipTypeId, relReq.IsReverse); if (direction == Direction.Reverse) { key = -key; } _result.Relationships [key] = new RelationshipInfo { CloneAction = relEntity.CloneAction_Enum ?? CloneActionEnum_Enumeration.Drop, ReverseCloneAction = relEntity.ReverseCloneAction_Enum ?? CloneActionEnum_Enumeration.Drop, IsLookup = relEntity.IsLookup(direction), ImpliesSecurity = (direction == Direction.Forward ? relEntity.SecuresTo : relEntity.SecuresFrom) ?? false || (relReq.RelationshipTypeId.Alias == "isOfType" && relReq.RelationshipTypeId.Namespace == "core" && !relReq.IsReverse) // Allow types to be loaded implicitly, without granting write to the type. }; } }