winforms EF核心,下拉组合框绑定到绑定源,有没有一个下降的方式来持久化新添加的项目?绑定列表?

d7v8vwbk  于 2023-01-14  发布在  其他
关注(0)|答案(1)|浏览(107)

我正在尝试构建患者编辑表单,该表单将使用EF Core和DbContext衍生的AppDbContext从数据库中获取患者数据。
在同一个表单上,将有一个下拉组合框,显示所有可用的保险(从数据库中提取)。
我想要实现的是用户能够选择现有保险(这是显而易见且容易实现的)或通过在组合框中键入新保险来添加新保险的能力,并且从现在开始直到SaveChanges发生以及同一患者重新打开进行编辑时,该新条目应被选为患者的保险。
我使用两个BindingSource,一个用于患者本身(bsPatient),一个用于保险列表(bsInsurances)。
我有以下两个模型(一对多关系)

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();
    }
}

到目前为止,当选择了一个已经存在的项目时,我能够正确地保存组合框中的保险选择。当用户在组合文本框中插入一个新的保险条目时,问题出现了。这个新条目不能保存到数据库中,也不能在下次打开同一患者进行编辑时显示。
如果有人能告诉我应该遵循哪个方向来实现这一点,我将不胜感激。我的意思是,在编辑患者数据时,如何能够在保险组合中插入一个新条目,以及如何将这个新条目持久化到数据库中,并在下次打开患者进行编辑时显示和选择。

ijnw1ujt

ijnw1ujt1#

我想我已经找到了一个解决方案。我不知道这是否是最好的一个,但它似乎是工作,至少到我的项目。我只是指它的情况下,其他人有同样的查询。请如果有人有一个更好的解决方案,我会很感激他/她的帮助。

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();
    }

相关问题