我遇到问题已经有一段时间了,我已经用尽了所有方法来为自己解决这个问题。
我在 MS Sharepoint 2010 环境中有 2 个列表,其中包含医疗组的个人医生数据……没什么特别的,主要是文本字段和一些查找选择字段。
我正在尝试编写一个程序,将数据从列表 A 迁移到列表 B。我正在使用 LINQ to Sharepoint 来完成此操作。一切都编译得很好,但是当它运行并点击 SubmitChanges() 方法时,我收到一个运行时错误,指出:
“必须在提交更改之前添加/附加对象图中的所有新实体。”
这个问题一定超出了我的 C# 知识范围,因为我根本找不到解决方案。问题肯定源于某些列属于“查找”类型的事实,因为当我在 LINQ 查询中创建新的“医师”实体时,如果我注释掉处理查找列的字段,一切都会运行完美。
在包含查找列的情况下,如果我在 SubmitChanges() 方法之前调试并点击断点,我可以查看从旧列表创建的新“医师”实体和字段,包括查找列中的数据,看起来不错,数据以我想要的方式在那里,每当它尝试用新实体实际更新新列表时,它就会消失。
我尝试了几种解决此错误的方法,但均无济于事。特别是,我尝试创建一个全新的 EntityList 列表并在创建每个新的“医师”实体后调用 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;
}
}