我正在使用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()
答案 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;