无法跟踪实体类型“个人资料”的实例,因为已经跟踪了另一个键值为“ {Id:1087}”的实例

时间:2020-07-06 10:23:10

标签: c# .net-core entity-framework-core

我正在使用Entity Framework Core 5.0.0-preview.6.20312.4,Microsoft SQL Server2019。我发现错误

无法跟踪实体类型“配置文件”的实例,因为 键值为'{Id:1087}'的另一个实例已经存在 跟踪。连接现有实体时,请确保只有一个实体 附加了具有给定键值的实例。

我的代码

实体

using System;
using System.Collections.Generic;

namespace linkedin_mp.Models
{
    public partial class Profile
    {
        public decimal Id { get; set; }
        public string LinkedinUrl { get; set; }
        public string ProfileIdNumber { get; set; }
        public DateTime? Created { get; set; }
        public DateTime? Modified { get; set; }
        public decimal? Version { get; set; }
        public bool? IsTarget { get; set; }
    }
}

dbcontext

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using linkedin_mp.Models;

namespace linkedin_mp.Data
{
    public partial class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext()
        {
        }

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Profile> Profile { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
                optionsBuilder.UseSqlServer("Server=D1CMPS_VYDN;Database=linkedin;User Id=sa; Password=my_secret;Trusted_Connection=True;");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Profile>(entity =>
            {
                entity.Property(e => e.Id)
                    .HasColumnName("id")
                    .HasViewColumnName("id")
                    .HasColumnType("numeric(18, 0)")
                    .ValueGeneratedOnAdd();

                entity.Property(e => e.Created)
                    .HasColumnName("created")
                    .HasViewColumnName("created")
                    .HasColumnType("datetime");

                entity.Property(e => e.IsTarget)
                    .HasColumnName("isTarget")
                    .HasViewColumnName("isTarget");

                entity.Property(e => e.LinkedinUrl)
                    .HasColumnName("linkedin_url")
                    .HasViewColumnName("linkedin_url")
                    .HasMaxLength(2048);

                entity.Property(e => e.Modified)
                    .HasColumnName("modified")
                    .HasViewColumnName("modified")
                    .HasColumnType("datetime");

                entity.Property(e => e.ProfileIdNumber)
                    .HasColumnName("profile_id_number")
                    .HasViewColumnName("profile_id_number")
                    .HasMaxLength(50);

                entity.Property(e => e.Version)
                    .HasColumnName("version")
                    .HasViewColumnName("version")
                    .HasColumnType("numeric(18, 0)");
            });

            modelBuilder.Entity<ProfileDetail>(entity =>
            {
                entity.HasKey(x => x.DetailId)
                    .HasName("PK__profile___38E9A224D0C5029F");

                entity.ToTable("profile_detail");

                entity.Property(e => e.DetailId)
                    .HasColumnName("detail_id")
                    .HasViewColumnName("detail_id")
                    .HasColumnType("numeric(18, 0)")
                    .ValueGeneratedOnAdd();

                entity.Property(e => e.Birthday)
                    .HasColumnName("birthday")
                    .HasViewColumnName("birthday")
                    .HasColumnType("date");

                entity.Property(e => e.Email)
                    .HasColumnName("email")
                    .HasViewColumnName("email")
                    .HasMaxLength(512);

                entity.Property(e => e.ExperienceSetId)
                    .HasColumnName("experience_set_id")
                    .HasViewColumnName("experience_set_id")
                    .HasColumnType("numeric(18, 0)");

                entity.Property(e => e.FullAddress)
                    .HasColumnName("full_address")
                    .HasViewColumnName("full_address")
                    .HasMaxLength(2048);

                entity.Property(e => e.InstantMessageSetId)
                    .HasColumnName("instant_message_set_id")
                    .HasViewColumnName("instant_message_set_id")
                    .HasColumnType("numeric(18, 0)");

                entity.Property(e => e.InterestSetId)
                    .HasColumnName("interest_set_id")
                    .HasViewColumnName("interest_set_id")
                    .HasColumnType("numeric(18, 0)");

                entity.Property(e => e.ProfileAbout)
                    .HasColumnName("profile_about")
                    .HasViewColumnName("profile_about")
                    .HasMaxLength(2048);

                entity.Property(e => e.ProfileAddress)
                    .HasColumnName("profile_address")
                    .HasViewColumnName("profile_address")
                    .HasMaxLength(1024);

                entity.Property(e => e.ProfileHeadEducation)
                    .HasColumnName("profile_head_education")
                    .HasViewColumnName("profile_head_education")
                    .HasMaxLength(1024);

                entity.Property(e => e.ProfileHeadJob)
                    .HasColumnName("profile_head_job")
                    .HasViewColumnName("profile_head_job")
                    .HasMaxLength(1024);

                entity.Property(e => e.ProfileHeadline)
                    .HasColumnName("profile_headline")
                    .HasViewColumnName("profile_headline")
                    .HasMaxLength(1024);

                entity.Property(e => e.ProfileId)
                    .HasColumnName("profile_id")
                    .HasViewColumnName("profile_id")
                    .HasColumnType("numeric(18, 0)");

                entity.Property(e => e.ProfileName)
                    .HasColumnName("profile_name")
                    .HasViewColumnName("profile_name")
                    .HasMaxLength(1024);

                entity.Property(e => e.SkillSetId)
                    .HasColumnName("skill_set_id")
                    .HasViewColumnName("skill_set_id")
                    .HasColumnType("numeric(18, 0)");

                entity.Property(e => e.ToolTechSetId)
                    .HasColumnName("tool_tech_set_id")
                    .HasViewColumnName("tool_tech_set_id")
                    .HasColumnType("numeric(18, 0)");
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}
        [HttpGet]
        [Route("getprofile")]
        public IEnumerable<string> Get2()
        {
            List<string> list = new List<string>();
            using IWebDriver driver = new FirefoxDriver();
            WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
            driver.Navigate().GoToUrl("https://www.linkedin.com/");
            driver.FindElement(By.ClassName("nav__button-secondary")).SendKeys(Keys.Return);
            driver.FindElement(By.Id("username")).SendKeys("my_username");
            driver.FindElement(By.Id("password")).SendKeys("my_password" + Keys.Enter);
            ApplicationDbContext dbContext = new ApplicationDbContext();
            var profilesList = from p in dbContext.Profile
                               where p.Id >= 1087 && p.Id <=1226 
                               select p;
            List<Profile> profiles = profilesList.ToList<Profile>();
            List<string> links = new List<string>();
            int count = profiles.Count();
            for (int i = 0; i < profilesList.Count(); i++)
            {
                driver.Navigate().GoToUrl(profiles[i].LinkedinUrl);
                Profile profile = new Profile();
                profile.Id = profiles[i].Id;
                IWebElement webElement1 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("li.inline.t-24.t-black.t-normal.break-words")));
                string profile_name = webElement1.GetAttribute("innerHTML").Trim();
                profile.ProfileName = profile_name;

                // profile_headline
                IWebElement webElement2 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("h2.mt1")));
                string profile_headline = webElement2.GetAttribute("innerHTML").Trim();
                Console.WriteLine("profile_headline = " + profile_headline);
                profile.ProfileHeadline = profile_headline;

                // short_address
                IWebElement webElement3 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("li.t-16.t-black.t-normal.inline-block")));
                string short_address = webElement3.GetAttribute("innerHTML").Trim();
                Console.WriteLine("sort_address = " + short_address);
                profile.ProfileAddress = short_address;

                dbContext.Profile.Update(profile);
                dbContext.SaveChangesAsync();
                Console.WriteLine("Save to profile_detail success.");
                Console.WriteLine("--------------------------------");

                // profile_address . đang sai
                // IWebElement webElement4 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("h2.mt1")));
                // Console.WriteLine("profile_address = " + webElement4.GetAttribute("innerHTML").Trim());

                // full_address. chưa lấy được từ pop-up.
                // IWebElement webElement5 = webDriverWait.Until(ExpectedConditions.ElementExists(By.XPath("//*[@id[starts-with(., 'ember')]/div/section[2]/div/a")));
                // Console.WriteLine(webElement5.GetAttribute("innerHTML").Trim());
            }
            return list;
        }

错误:

System.InvalidOperationException
  HResult=0x80131509
  Message=The instance of entity type 'Profile' cannot be tracked because another instance with the key value '{Id: 1087}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
  Source=Microsoft.EntityFrameworkCore
  StackTrace:
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.Update[TEntity](TEntity entity)
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Update(TEntity entity)
   at linkedin_mp.Controllers.LinkedInController.Get2() in E:\github\xxx\linkedin_crawler\Controllers\LinkedInController.cs:line 279
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()

2 个答案:

答案 0 :(得分:2)

您可以重复使用现有的配置文件。代替:

Profile profile = new Profile();
profile.Id = profiles[i].Id;

您只需将profiles[i]分配给profile

Profile profile = profiles[i];

答案 1 :(得分:0)

使用新的(另一个)Dbcontext添加操作

ApplicationDbContext dbContext2 = new ApplicationDbContext();

更多细节:

ApplicationDbContext dbContext2 = new ApplicationDbContext();

            for (int i = 0; i < profilesList.Count(); i++)
            {
                driver.Navigate().GoToUrl(profiles[i].LinkedinUrl);
                Profile profile = new Profile();

                profile.Id = profiles[i].Id;

                IWebElement webElement1 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("li.inline.t-24.t-black.t-normal.break-words")));
                string profile_name = webElement1.GetAttribute("innerHTML").Trim();
                Console.WriteLine("profile_name = " + profile_name);
                profile.ProfileName = profile_name;

                // profile_headline
                IWebElement webElement2 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("h2.mt1")));
                string profile_headline = webElement2.GetAttribute("innerHTML").Trim();
                Console.WriteLine("profile_headline = " + profile_headline);
                profile.ProfileHeadline = profile_headline;

                // short_address
                IWebElement webElement3 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("li.t-16.t-black.t-normal.inline-block")));
                string short_address = webElement3.GetAttribute("innerHTML").Trim();
                Console.WriteLine("sort_address = " + short_address);
                profile.ProfileAddress = short_address;

                dbContext2.Profile.Update(profile);
                dbContext2.SaveChangesAsync();
                Console.WriteLine("Save to profile_detail success.");
                Console.WriteLine("--------------------------------");

                // profile_address . đang sai
                // IWebElement webElement4 = webDriverWait.Until(ExpectedConditions.ElementExists(By.CssSelector("h2.mt1")));
                // Console.WriteLine("profile_address = " + webElement4.GetAttribute("innerHTML").Trim());

                // full_address. chưa lấy được từ pop-up.
                // IWebElement webElement5 = webDriverWait.Until(ExpectedConditions.ElementExists(By.XPath("//*[@id[starts-with(., 'ember')]/div/section[2]/div/a")));
                // Console.WriteLine(webElement5.GetAttribute("innerHTML").Trim());
            }
            return list;