首先,我是ADO.NET,LINQ和那些数据访问技术的新手。据我所知,我在互联网上发现了什么,LINQ2SQL演变为LINQ到演变为ADO.NET的实体。也许我对这些概念不对,所以请告诉我。
现在回答这个问题。我正在使用ADO.NET在VS2010(.NET 4.0)中开发一个系统来管理学校。该解决方案分为3层:表示层(仅GUI),业务层(此处完成所有流程)和数据层(仅查询和数据库访问)。
数据库有一个表人员用于存储人员(学生,教师,行政等)的数据,其中包含国籍字段,该字段存储了所有现有国家/地区对“国家/地区”表的引用。
在我的第一个方法中,我创建了一个名为ConnectionManager的单例类,它存储连接字符串和对数据库模型的引用(由ADO.NET实体数据模型设计器生成的代码),一个继承自ObjectContext的对象,称为SystemEntities
此时一切都很好,但是我想知道以下情况:当客户到达时,用户正在编辑人员信息并请求支付账单;然后用户切换到账单表格,填写数据并在打印前保存。在此过程中,调用SystemEntities.SaveChanges以便将所有更改保存到数据库中,然后保存对已编辑人员所做的未完成更改,但这是一种不良行为。
然后我开始说我必须没有一个能够保持与数据库的连接打开的单例。每个ObjectContext都可以在获取数据之后处理,因此应该使用像这样的代码。
要抓取所有人
public static T[] QueryAll<T>() where T : Person
{
using (SystemEntities context = ConnectionManager.Instance.GetContext())
{
return context.People
.OfType<T>()
.Include("Emails")
.Include("Phones")
.OrderBy(affiliate => affiliate.LastName + " " + affiliate.FirstName)
.ToArray();
}
}
获取国家/地区
public static Country GetByID(string id)
{
using (SystemEntities context = ConnectionManager.Instance.GetContext())
{
return context.Countries.FirstOrDefault(country => country.CountryID == id);
}
}
现在,当我尝试编辑一个人时,要具体改变一个人的国家,就会出现异常:
The relationship between the two objects cannot be defined
because they are attached to different ObjectContext objects.
这可以通过以下代码完成:
public Person Person
{
get { ... }
set
{
this.person = value;
...
this.cmbNationality.DataBindings.Add("SelectedItem", person, "Nationality");
this.cmdAddressCountry.DataBindings.Add("SelectedItem", person, "Country");
...
}
}
private void form_Load(object sender, EventArgs e)
{
Country[] countries = Country.QueryAll();
Country mexico = Country.GetByA2("MX");
this.cmbNationality.DataSource = countries;
this.cmdAddressCountry.DataSource = countries;
this.cmbNationality.SelectedItem = mexico;
this.cmdAddressCountry.SelectedItem = mexico;
}
因此,当您更改cmbNationality和cmdAddressCountry组合框中的项目时,将引发异常。请注意,这只是一个更改,没有执行保存。
据我所知,这是因为Person和Country对象是从不同的SystemEntities(ObjectContext)对象从数据库中提取的。
还有问题和疑问。如果我不能使用单例并且所有上下文必须在使用后丢弃,我该如何解决?当然我可以创建几个方法来避免这个问题,手工更新或不使用数据绑定,但是,如果你必须手头有更新,那么ADO.NET有什么意义呢?
可能是一个愚蠢或微不足道的(或者我可能只是不知道如何搜索答案)问题,但我无法找到答案。
提前致谢
答案 0 :(得分:1)
为什么不在类中设置全局对象“System Entities context”,在构造函数中使用\
"context = ConnectionManager.Instance.GetContext()"
,所以你会得到相同的
SystemEntities (ObjectContext) objects.
我希望它可以帮到你。
答案 1 :(得分:1)
听起来你正在使用标准的断开模型。由于您已断开连接,因此只要持久保存修改后的对象,您就必须从当前上下文中重新保存实体。以下希望更能说明我的意思:
public static Person PersistPerson(Person person)
{
using (SystemEntities context = ConnectionManager.Instance.GetContext())
{
bool doInsert = false;
var p = context.People.Where(d => d.PersonId == person.PersonId).FirstOrDefault();
if (p == null)
{
p = new Person();
doInsert = true;
}
//update connected Entity
p.LastName = person.LastName;
p.Emails = person.Emails;
//etc...
if(doInsert)
context.People.AddObject(person);
context.SaveChanges();
person.PersonId = p.PersonId;
}
return person;
}