属性“Id”是对象关键信息的一部分

时间:2018-03-01 15:55:45

标签: c# asp.net sql-server entity-framework asp.net-web-api

  

另一个异常可能来自相同的错误 - 对...的更改   数据库已成功提交,但发生错误   更新对象上下文。 ObjectContext可能位于   不一致的状态。内部异常消息:保存或接受   更改失败,因为多个类型的实体   'ClientDataStore.Logger.DB.Core.AuditLog'具有相同的主键   值。确保显式设置的主键值是唯一的。   确保正确配置数据库生成的主键   在数据库和实体框架模型中。使用实体   Database First / Model First配置的Designer。使用   'HasDatabaseGeneratedOption“”流畅的API或   用于Code First配置的'DatabaseGeneratedAttribute';   属性“Id”是对象的关键信息的一部分,但不能   被修改

我有一个Asp.Net WebAPI应用程序,它正在使用实体框架Code First模型,我正在记录每个请求。为此目的,有一个继承DelegatingHandler的类。 我已经覆盖了SendAsync方法。

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {

        // Get data from token
        IPrincipal _currentUser = HttpContext.Current.User;
        // Start watch to count Milliseconds of execution of request.
        var watch = Stopwatch.StartNew();

        var result = await base.SendAsync(request, cancellationToken);

        // Stop watch after request is complete
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;            

        try
        {
            bool isRestLoggerEnabled = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["RestLoggerEnabled"]);
            if (isRestLoggerEnabled && request.Headers.Authorization != null)
            {
                var requestBody = string.Empty;
                using (var reader = new StreamReader(request.Content.ReadAsStreamAsync().Result))
                {
                    reader.BaseStream.Seek(0, SeekOrigin.Begin);
                    requestBody = reader.ReadToEnd();
                }

                AuditLog al = new AuditLog();
                al.CreateDate = DateTime.Now;
                al.HTTPMethod = request.Method.Method;
                al.RequestData = requestBody;
                al.ResponseData = result.Content.ReadAsStringAsync().Result.ToString();
                al.DurationMS = TimeSpan.FromMilliseconds(elapsedMs);
                al.HTTPResponseCode = ((int)result.StatusCode).ToString();
                al.RequestHeaders = request.Headers.ToString();
                al.RequestURL = request.RequestUri.ToString();
                if ((int)result.StatusCode != (int)HttpResponseStatusCodeTypes.Unauthorized)
                {
                    al.UserId = ((_currentUser.Identity as ClaimsIdentity).FindFirst("UserId") != null ? long.Parse((_currentUser.Identity as ClaimsIdentity).FindFirst("UserId").Value) : 0);
                    al.UserPartyId = ((_currentUser.Identity as ClaimsIdentity).FindFirst("UserPartyId") != null ? long.Parse((_currentUser.Identity as ClaimsIdentity).FindFirst("UserPartyId").Value) : 0);
                    al.PlatformId = ((_currentUser.Identity as ClaimsIdentity).FindFirst("PlatformId") != null ? long.Parse((_currentUser.Identity as ClaimsIdentity).FindFirst("PlatformId").Value) : 0);
                    al.ProductId = ((_currentUser.Identity as ClaimsIdentity).FindFirst("ProductId") != null ? long.Parse((_currentUser.Identity as ClaimsIdentity).FindFirst("ProductId").Value) : 0);
                }
                unitOfWork.LoggerRepository<AuditLog>().Add(al);
                unitOfWork.Save();
            }
        }
        catch(Exception ex)
        {
            loggerManager.Critical(ex, "AuditLogger exception");
        }

        // Log responce and request + time and other 
        if (result.Content != null)
        {
            // once response body is ready, log it
            var responseBody = await result.Content.ReadAsStringAsync();
            Trace.WriteLine(responseBody);
        }

        return result;
    }

这是表格的模型。

public class AuditLog : LoggerEntityBase
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    //[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime? CreateDate { get; set; }

    public string RequestData { get; set; }

    public string ResponseData { get; set; }

    [MaxLength(3)]
    public string HTTPResponseCode { get; set; }

    public long UserId { get; set; }

    public long UserPartyId { get; set; }

    public long PlatformId { get; set; }

    public long ProductId { get; set; }

    public long ClientId { get; set; }

    [MaxLength(2000)]
    public string RequestURL { get; set; }

    public string HTTPMethod { get; set; }

    public string RequestHeaders { get; set; }

    public TimeSpan DurationMS { get; set; }
 }

我还在使用unitOfWork和Repository模式。 在应用程序收到大量请求的那一刻,可能每10-15分钟就有1000个请求,并且在某些时候我得到了这些例外,而不是每次请求,但是他们每隔5-10分钟就会不断发出这样的事情或类似的事情。 。 在我看来,可能导致问题的一件事是 - 记录器正在保存的每条记录都有大量数据(如7k-10k字符)。如果应用程序一次收到许多请求,并且每个请求都包含如此多的数据,则无法使用db记录这么快,并且开始弄乱它的PK id-s。 PK是标准的sql生成的大型int。

有没有人对此处可能发生的事情有任何其他想法?

0 个答案:

没有答案