C# 实体框架代码第一表关系
我有一个C#应用程序,它连接到一个Web API,该API为我的应用程序提供一些房地产代理列表和代理的XML数据 XML大致如下所示:C# 实体框架代码第一表关系,c#,.net,entity-framework,database-design,entity-framework-6,C#,.net,Entity Framework,Database Design,Entity Framework 6,我有一个C#应用程序,它连接到一个Web API,该API为我的应用程序提供一些房地产代理列表和代理的XML数据 XML大致如下所示: <Snapshot> <Agents> <Agent id="838388" firstName="John" surname="Smith"/> <Agent id="838389" firstName="Jane" surname="Doe"/> &l
<Snapshot>
<Agents>
<Agent id="838388" firstName="John" surname="Smith"/>
<Agent id="838389" firstName="Jane" surname="Doe"/>
<Agent id="838390" firstName="Mary" surname="Appleton"/>
<Agent id="838391" firstName="Peter" surname="Gill"/>
</Agents>
<Listings>
<Listing id="1737672" officeId="801948" agencyName="Century 21">
<Agents>
<AgentRef id="838388" />
<AgentRef id="838391" />
</Agents>
</Listing>
<Listing id="1737673" officeId="801949" agencyName="Remax">
<Agents>
<AgentRef id="838390" />
<AgentRef id="838389" />
</Agents>
</Listing>
</Listings>
</Snapshot>
我决定使用EntityFramework6.2,代码优先的方法。所以我创建了这两个类:
public class Agent
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AgentId { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public virtual ICollection<Listing> Listings { get; set; }
}
公共类代理
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
公共int代理{get;set;}
公共字符串名{get;set;}
公共字符串姓氏{get;set;}
公共虚拟ICollection列表{get;set;}
}
及
公共类列表
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
public int ListingId{get;set;}
public int OfficeId{get;set;}
公共int代理名称{get;set;}
公共虚拟ICollection代理{get;set;}
}
如您所见,代理和列表之间存在多对多关系。所以一个代理可以有零个或多个列表与他关联,而一个列表可以有零个或多个代理与之关联
因此,我的应用程序读取第一个标记中的所有代理,并将所有代理插入代理表。然后,稍后,当它读取所有列表时,看起来EF正在尝试再次创建这些代理。显然,这会导致主键冲突错误,因为它试图再次添加具有相同ID的第二个代理
我正在使用XDocument解析XML。这是我阅读清单中AgentRef元素的位置:
XElement root = xDoc.Root.Elements("Listings").Descendants("Listing");
if (root.Descendants("Agents").Any())
{
List<string> agentRefs = root.Element("Agents").Elements("AgentRef")
.Select(a => a.Attribute("id").Value).ToList();
listing.AgentRefs = agentRefs.Select(int.Parse).ToList();
}
XElement root=xDoc.root.Elements(“清单”).substands(“清单”);
if(root.substands(“代理”).Any())
{
List agentRefs=root.Element(“Agents”).Elements(“AgentRef”)
.Select(a=>a.Attribute(“id”).Value).ToList();
listing.AgentRefs=AgentRefs.Select(int.Parse.ToList();
}
有什么办法可以解决这个问题吗?如果代理已经存在于数据库中,您必须通过将代理附加到上下文中来说明:
using(var myContext = new MyContext)
{
var agent = new Agent() { AgentId = 838388 };
myContext.Agents.Attach(agent);
var listing = new Listing() { ... };
listing.Agents.Add(agent);
myContext.Listings.AddObject(listing);
myContext.SaveChanges();
}
请包括处理列表的相关代码。还要指定是否使用同一个
DbContext
实例来插入代理和列表。感谢您的回复。我只使用一个DbContext。基本上,我的XML解析例程返回一个“快照”类,该类包含一组代理和一组列表。然后,我循环遍历代理和清单集合,将每个项添加到dbContext,并在末尾调用dbContext.SaveChanges();在上面的清单类中,我试图将:public virtual ICollection Agents{get;set;}替换为public virtual ICollection AgentRefs{get;set;},以更好地反映XML。但这不会创建EF正确完成工作并创建Listings Agent桥接表所需的导航属性,是吗?我也在这里发布了它-也许我解释得稍微好一点?不,实体模型还可以,只是应用更改的代码(未显示)很可能不正确。谢谢Duy。我现在得到以下信息:)附加“Agent”类型的实体失败,因为相同类型的另一个实体已经具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在使用“Attach”方法或将实体状态设置为“Unchanged”或“Modified”时可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“Add”方法或“Added”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“Unchanged”或“Modified”。我也在这里发布了它。。。也许我解释得稍微好一点?
using(var myContext = new MyContext)
{
var agent = new Agent() { AgentId = 838388 };
myContext.Agents.Attach(agent);
var listing = new Listing() { ... };
listing.Agents.Add(agent);
myContext.Listings.AddObject(listing);
myContext.SaveChanges();
}