gpt4 book ai didi

c# - LINQ to SharePoint 2010 出现错误 "All new entities within an object graph must be added/attached before changes are submitted."

转载 作者:太空宇宙 更新时间:2023-11-03 11:17:33 24 4
gpt4 key购买 nike

我遇到一个问题已经有一段时间了,我已经用尽了所有办法自己解决这个问题。

我在 MS Sharepoint 2010 环境中有 2 个列表,它们保存着一个医疗组的个人医生数据...没什么特别的,主要是文本字段和一些查找选择字段。

我正在尝试编写一个程序,将数据从列表 A 迁移到列表 B。我正在使用 LINQ to Sharepoint 来完成此操作。一切都编译得很好,但是当它运行并调用 SubmitChanges() 方法时,我收到一个运行时错误,指出:

“在提交更改之前,必须添加/附加对象图中的所有新实体。”

这个问题一定超出了我的 C# 知识范围,因为我根本找不到解决方案。问题肯定源于某些列的类型为“Lookup”这一事实,因为当我在 LINQ 查询中创建一个新的“Physician”实体时,如果我注释掉处理查找列的字段,一切都会运行完美。

在包含查找列的情况下,如果我在 SubmitChanges() 方法之前调试并命中断点,我可以查看从旧列表和字段创建的新“Physician”实体,包括来自查找列的数据,看起来不错,数据以我想要的方式存在,每当它尝试使用新实体实际更新新列表时,它就会消失。

我尝试了多种解决此错误的方法,但都无济于事。特别是,我尝试创建一个全新的 EntityList 列表并在创建每个新的“Physician”实体后调用 Attach() 方法,但无济于事,它只是让我转了一圈,追逐其他错误,例如“ID不能为空”、“不能插入已删除的实体”等,

与我第一次收到此错误时相比,我现在并没有走得太远,任何人都可以提供的任何帮助都将不胜感激。

这是我的代码:

using (ProviderDataContext ctx = new ProviderDataContext("http://dev"))
{

SPSite sitecollection = new SPSite("http://dev");
SPWeb web = sitecollection.OpenWeb();
SPList theOldList = web.Lists.TryGetList("OldList_Physicians");

//Create new Physician entities.
foreach(SPListItem l in theOldList.Items)
{
PhysiciansItem p = new PhysiciansItem()
{
FirstName = (String)l["First Name"],
Title = (String)l["Last Name"],
MiddleInitial = (String)l["Middle Init"],
ProviderNumber = Convert.ToInt32(l["Provider No"]),
Gender = ConvertGender(l),
UndergraduateSchool =(String)l["UG_School"],
MedicalSchool = (String)l["Med_School"],
Residency = (String)l["Residency"],
Fellowship = (String)l["Fellowship"],
Internship = (String)l["Internship"],
PhysicianType = ConvertToPhysiciantype(l),
Specialty = ConvertSpecialties(l),
InsurancesAccepted = ConvertInsurance(l),
};
ctx.Physicians.InsertOnSubmit(p);
}

ctx.SubmitChanges(); //this is where it flakes out
}
}


//Theses are conversion functions that I wrote to convert the data from the old list to the new lookup columns.

private Gender ConvertGender(SPListItem l)
{
Gender g = new Gender();
if ((String)l["Sex"] == "M")
{
g = Gender.M;
}
else g = Gender.F;
return g;

}

//Process and convert the 'Physician Type', namely the distinction between MD (Medical Doctor) and
//DO (Doctor of Osteopathic Medicine). State Regualtions require this information to be attached
//to a physician's profile.
private ProviderTypesItem ConvertToPhysiciantype(SPListItem l)
{
ProviderTypesItem p = new ProviderTypesItem();
p.Title = (String)l["Provider_Title:Title"];
p.Intials = (String)l["Provider_Title"];

return p;
}

//Process and convert current Specialty and SubSpecialty data into the single multi-choice lookup column
private EntitySet<Item> ConvertSpecialties(SPListItem l)
{
EntitySet<Item> theEntityList = new EntitySet<Item>();
Item i = new Item();
i.Title = (String)l["Provider Specialty"];
theEntityList.Add(i);

if ((String)l["Provider SubSpecialty"] != null)
{
Item theSubSpecialty = new Item();
theSubSpecialty.Title = (String)l["Provider SubSpecialty"];
theEntityList.Add(theSubSpecialty);
}

return theEntityList;
}


//Process and add insurance accepted.
//Note this is a conversion from 3 boolean columns in the SP Environment to a multi-select enabled checkbox
//list.
private EntitySet<Item> ConvertInsurance(SPListItem l)
{
EntitySet<Item> theEntityList = new EntitySet<Item>();
if ((bool)l["TennCare"] == true)
{
Item TenncareItem = new Item();
TenncareItem.Title = "TennCare";
theEntityList.Add(TenncareItem);

}
if ((bool)l["Medicare"] == true)
{
Item MedicareItem = new Item();
MedicareItem.Title = "Medicare";
theEntityList.Add(MedicareItem);
}
if ((bool)l["Commercial"] == true)
{
Item CommercialItem = new Item();
CommercialItem.Title = "Commercial";
theEntityList.Add(CommercialItem);
}
return theEntityList;

}
}

最佳答案

所以这可能不是您正在寻找的答案,但它是过去对我有用的答案。我发现使用 Linq to Sharepoint 更新查找字段非常令人沮丧。它经常不起作用,或者不能有效地工作(迫使我通过 ID 查询项目只是为了设置查找值)。

您可以设置实体,使其具有一个用于查找 ID(对于每个查找字段)的 int 属性和一个用于查找值的字符串属性。如果,当您使用 SPMetal 生成实体时,您没有生成正在查找的列表,那么它将自行执行此操作。我喜欢做的是(以你的实体为例)

  1. 在某个临时文件夹中仅为该列表(Physicians)生成实体
  2. 为每个查找(或我感兴趣的查找)提取查找 ID 和值的属性(也将有私有(private)支持字段也需要一起使用)
  3. 在我的实际项目文件中为 Physicians 创建部分类文件,以便正常重新生成整个 SPMetal 文件(不限于仅该列表)不会覆盖更改
  4. 将查找 ID 和值属性粘贴到此部分 Physicians 类中。

现在每个查找字段都有 3 个属性。例如,对于 PhysicianType 将有:

  • PhysicianType,这是当前存在的类型。这在查询数据时非常有用,因为您可以非常轻松地执行联接等操作。
  • PhysicianTypeId 如果您只需要 ID,它偶尔可用于查询,因为它使它更简单一些,但大多数情况下我在设置值时使用它。要设置查找字段,您只需设置 ID。这很容易,而且根据我的经验,在实际(正确)工作方面有良好的记录。
  • PhysicianTypeValue 如果您只需要查找值作为字符串(这意味着它将是原始值,而不是已经解析的东西,如果它是一个多值字段,则它在执行查询时可能很有用,或者用户字段等。有时候我宁愿自己解析它,或者可能只是在开发时看看底层值是什么。即使你不用它而使用第一个属性,我也经常带着它来做因为我已经完成了大部分工作来完成 PhysicianTypeId 字段。

这似乎有点 hacky,并且与 linq-to-SharePoint 的一般设计相反。我同意,但它也有实际工作的优势,而且实际上并不那么困难(一旦你了解它的节奏并了解究竟需要复制什么才能将属性从一个文件移动到另一个文件)。

关于c# - LINQ to SharePoint 2010 出现错误 "All new entities within an object graph must be added/attached before changes are submitted.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12182339/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com