我正在尝试构建一个患者的编辑表单,该表单将使用EF Core和DbContext
派生的AppDbContext
从数据库中获取患者数据。
在同一表单上将有一个下拉组合框,将显示所有可用的保险(从数据库获取)。
我想要实现的是这样一种能力,用户能够选择一个现有的保险(这是显而易见的,很容易实现的),或者通过在组合框中输入一个新的保险,这个新的条目应该被选择为患者的保险,从现在开始,直到SaveChanges
发生,当同一患者被重新打开进行编辑。
我使用了两个binding source,一个用于患者本身(bsPatient
),一个用于保险列表(bsInsurances
)。
我有以下两个模型(1:多关系)
public class Insurance
{
public int Id { get; set; }
public string Name { get; set; } = String.Empty;
public virtual ObservableCollectionListSource<Person> Persons { get; } = new();
}
public class Person
{
public int Id { get; set; }
public string LastName { get; set; } = String.Empty;
public string FirstName { get; set; } = String.Empty;
public DateTime DOB { get; set; }
public int InsuranceId { get; set; }
public Insurance Insurance { get; set; } = null;
}
这是DbContext
:
public class AppDbContext : DbContext
{
private const string DatabaseFileName = "MyPatientsDB.sqlite3";
public DbSet<Person> Persons { get; set; }
public DbSet<Insurance> Insurances { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder
.UseSqlite(@$"Data Source={DatabaseFileName}");
表单上会有
public partial class PatientForm : Form
{
private AppDbContext _db = new();
private int _patientId = 0;
ObservableCollection<Insurance> _insurancesList = new();
public PatientForm(int patientId)
{
InitializeComponent();
_patientId = patientId;
}
protected async override void OnLoad(EventArgs e)
{
base.OnLoad(e);
await _db.Insurances.LoadAsync();
_insurancesList = new ObservableCollection<Insurance>(_db.Insurances.Local);
bsInsurances.DataSource = _insurancesList;
bsPatient.DataSource = await _db.Persons.FirstOrDefaultAsync(p => p.Id == _patientId);
}
protected async override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
bsInsurances.EndEdit();
if (cbInsurances.FindStringExact(cbInsurances.Text) == -1)
{
var newInsurance = new Insurance { Id = 0, Name = cbInsurances.Text };
_db.Insurances.Local.Add(newInsurance);
}
bsPatient.EndEdit();
await _db.SaveChangesAsync();
_db?.Dispose();
}
}
到目前为止,当选择了一个已经存在的项目时,我能够正确地保存组合框的Insurance选择。当用户在组合文本框中插入新的保险条目时,问题就出现了。这个新条目不能保存到数据库中,并在下次打开同一患者进行编辑时显示。
如果有人能指出我应该遵循哪个方向来实现这个目标,我会很感激。我的意思是,在编辑患者数据时,如何能够将新条目插入到保险组合中,并将此新条目持久化到数据库中,并在下次打开患者进行编辑时显示和选择。
我想我找到解决办法了。我不知道它是否是最好的,但它似乎至少在我的项目中起作用。我只是引用它,以防有人有同样的疑问。如果有人有更好的解决办法,我将非常感谢他/她的帮助。
protected async override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
bsInsurances.EndEdit();
if (cbInsurances.FindStringExact(cbInsurances.Text) == -1)
{
if (bsPatient != null && bsPatient.DataSource != null)
{
(bsPatient.DataSource as Person).Insurance = new Insurance() { Name = cbInsurances.Text as string };
}
}
bsPatient.EndEdit();
await _db.SaveChangesAsync();
_db?.Dispose();
}