我面临一个奇怪的问题。当我将记录插入主键作为已定义的标识的表中时,将始终插入Id 1的新记录。我很遗憾为什么会这样。如果表中存在重复的主键,则完整性将丢失。
这是表结构
问题是由于交易中的上下文不同而引起的。 我在不同的用户活动中将点插入到不同的表中。因此,对于1个活动,多个用户可以获得将插入到多个表中的点,并用于保存已创建多个任务的点。
这是被称为
的方法之一 public async Task<MethodResult> AddPointsForPollVote(int UserId, int PollOptionId)
{
using (var transaction = _entities.Database.BeginTransaction())
{
try
{
var PostId = await GetPostMasterIdFromOption((int)GamificationItemType.Poll, PollOptionId);
var PostOwner = await GetOwnerOfThePost((int)GamificationItemType.Poll, PostId);
var OptionOwner = await GetOwnerOfThePostOptions((int)GamificationItemType.Poll, PollOptionId);
List<int> tagIds = _entities.PollTags.Where(x => x.Id == PostId).Select(x => x.TagId).ToList();
List<Task> lst = new List<Task>();
if (await CheckIfDailyPointLimitExceded((int)GamificationUserActions.Poll_Vote_Points_To_User, UserId) == false) // User limit not exceeded
{
// Add Daily Activity Point For User
var DailyActivityResultForUser = AddDailyActivityPointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_User, (int)GamificationItemType.Poll, UserId);
lst.Add(DailyActivityResultForUser);
// Add Total Redeemable Point For User
var TotalRedeemablePointsForUser = AddOrUpdateTotalRedeemablePointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_User, UserId);
lst.Add(TotalRedeemablePointsForUser);
// Add Total Point For User
var TotalPointsForUser = AddOrUpdateTotalPointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_User, UserId);
lst.Add(TotalPointsForUser);
// Add Topic Points For User
var TopicPointsForUser = AddOrUpdatePointsForTags((int)GamificationUserActions.Poll_Vote_Points_To_User, tagIds, UserId);
lst.Add(TopicPointsForUser);
// Add Topic points For maintaining User Level
var TopicPointLevelForUser = AddOrUpdatePointsLevelForTags((int)GamificationUserActions.Poll_Vote_Points_To_User, tagIds, UserId);
lst.Add(TopicPointLevelForUser);
// Add Daily Topic points For user
var DailyTopicPointLevelForUser = AddDailyTopicWisePoints((int)GamificationUserActions.Poll_Vote_Points_To_User, tagIds, UserId);
lst.Add(DailyTopicPointLevelForUser);
}
if (await CheckIfDailyPointLimitExceded((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner, OptionOwner) == false) // Option Owners limit not exceeded
{
// Add Daily Activity Point to Option Owner
var DailyActivityResultForOptionOwner = AddDailyActivityPointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner,(int)GamificationItemType.Poll,OptionOwner);
lst.Add(DailyActivityResultForOptionOwner);
// Add Total Redeemable Point to Option Owner
var TotalRedeemablePointsForOptionOwner = AddOrUpdateTotalRedeemablePointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner, OptionOwner);
lst.Add(TotalRedeemablePointsForOptionOwner);
// Add Total Point to Option Owner
var TotalPointsForOptionOwner = AddOrUpdateTotalPointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner, OptionOwner);
lst.Add(TotalPointsForOptionOwner);
// Add Topic Points For Option owner
var TopicPointsForOptionOwner = AddOrUpdatePointsForTags((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner, tagIds, OptionOwner);
lst.Add(TopicPointsForOptionOwner);
// Add Topic points For maintaining Option Owner Level
var TopicPointLevelForOptionOwner = AddOrUpdatePointsLevelForTags((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner, tagIds, OptionOwner);
lst.Add(TopicPointLevelForOptionOwner);
// Add Daily Topic points For Option Owner
var DailyTopicPointLevelForOptionOwner = AddDailyTopicWisePoints((int)GamificationUserActions.Poll_Vote_Points_To_Option_Owner, tagIds, OptionOwner);
lst.Add(DailyTopicPointLevelForOptionOwner);
}
if (await CheckIfDailyPointLimitExceded((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, PostOwner) == false) // Post Owners limit not exceeded
{
// Add Daily Activity Point to Post Owner
var DailyActivityResultForPollOwner = AddDailyActivityPointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, (int)GamificationItemType.Poll,PostOwner);
lst.Add(DailyActivityResultForPollOwner);
// Add Total Redeemable Point to Post Owner
var TotalRedeemablePointsForPostOwner = AddOrUpdateTotalRedeemablePointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, PostOwner);
lst.Add(TotalRedeemablePointsForPostOwner);
// Add Total Point to Post Owner
var TotalPointsForPollOwner = AddOrUpdateTotalPointsForUser((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, PostOwner);
lst.Add(TotalPointsForPollOwner);
// Add Topic Points For Post owner
var TopicPointsForPostOwner = AddOrUpdatePointsForTags((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, tagIds, PostOwner);
lst.Add(TopicPointsForPostOwner);
// Add Topic points For maintaining Post Owner Level
var TopicPointLevelForPostOwner = AddOrUpdatePointsLevelForTags((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, tagIds, PostOwner);
lst.Add(TopicPointLevelForPostOwner);
// Add Daily Topic points For Post Owner
var DailyTopicPointLevelForPostOwner = AddDailyTopicWisePoints((int)GamificationUserActions.Poll_Vote_Points_To_Poll_Owner, tagIds, PostOwner);
lst.Add(DailyTopicPointLevelForPostOwner);
}
await Task.WhenAll(lst);
transaction.Commit();
return new MethodResult() { Success = true, Message = "Points Added !!" };
}
catch (Exception ex)
{
transaction.Rollback();
return new MethodResult() { Success = false, Message = "There was some error !!" };
}
}
}
这是我被调用的方法之一,用于将数据插入表
public async Task AddDailyActivityPointsForUser(int ActionId, int ItemId, int UserId)
{
using (var context = new Entities())
{
try
{
DailyActivityPoint dailyActivityPoint = new DailyActivityPoint()
{
ActionId = ActionId,
CreatedDate = DateTime.Now,
ItemId = ItemId,
UserId = UserId,
PointsAccumulated = await GetPointsAwardedForAction(ActionId)
};
context.DailyActivityPoints.Add(dailyActivityPoint);
await context.SaveChangesAsync();
}
catch (Exception ex)
{
ErrorLog errorLog = new ErrorLog()
{
CreatedDate = DateTime.Now,
ErrorMessage = ex.Message,
ModuleName = "GamificationPointsService",
CustomMessage = " Error while Adding Daily Activity Points For user : AddDailyActivityPointsForUser ActionId : " + ActionId + " , ItemId : " + ItemId + " , UserId : " + UserId,
stackTrace = ex.StackTrace
};
context.ErrorLogs.Add(errorLog);
await context.SaveChangesAsync();
}
}
}
正如你所看到的,当我等待所有这些方法时,在事务内部调用了3个方法并且事务提交。 仅为某些表插入重复的主键。休息工作正常。 但问题是如何sql允许重复的主键。
请指导我。可能是什么问题。这是我编码的方式[不好的做法或其他什么,这是我第一次使用任务和异步编程[newbee:p]] ??
表脚本:
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Gamification].[DailyActivityPoints](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ActionId] [int] NOT NULL,
[ItemId] [int] NOT NULL,
[UserId] [int] NOT NULL,
[PointsAccumulated] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [Gamification].[DailyActivityPoints] ADD DEFAULT (getdate()) FOR [CreatedDate]
GO
ALTER TABLE [Gamification].[DailyActivityPoints] WITH CHECK ADD FOREIGN KEY([ActionId]) REFERENCES [Gamification].[ActionMaster] ([Id])
GO
ALTER TABLE [Gamification].[DailyActivityPoints] WITH CHECK ADD FOREIGN KEY([ItemId]) REFERENCES [Gamification].[ItemType] ([Id])
GO
ALTER TABLE [Gamification].[DailyActivityPoints] WITH CHECK ADD FOREIGN KEY([UserId]) REFERENCES [dbo].[Users] ([UserID])
GO