我正在编写一个无聊的应用程序来管理患者及其临床病史。我将 SQLite 与 DbLinq 库和 DbMetal 代码生成实用程序结合使用。以下是从底层数据库中提取的生成代码中的两个类:
[Table(Name="main.Patients")]
public partial class Patient : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
{
    private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs("");
    private long _birthday;
    private string _firstName;
    private int _hasChildren;
    private System.Nullable<int> _id;
    private int _isMarried;
    private string _lastName;
    private string _profession;
    private EntitySet<ClinicCase> _clinicCases;
    private EntitySet<PatientAddress> _patientsAddresses;
    private EntitySet<PatientPhoneNumber> _patientsPhoneNumbers;
    #region Extensibility Method Declarations
    partial void OnCreated();
    partial void OnBirthdayChanged();
    partial void OnBirthdayChanging(long value);
    partial void OnFirstNameChanged();
    partial void OnFirstNameChanging(string value);
    partial void OnHasChildrenChanged();
    partial void OnHasChildrenChanging(int value);
    partial void OnIDChanged();
    partial void OnIDChanging(System.Nullable<int> value);
    partial void OnIsMarriedChanged();
    partial void OnIsMarriedChanging(int value);
    partial void OnLastNameChanged();
    partial void OnLastNameChanging(string value);
    partial void OnProfessionChanged();
    partial void OnProfessionChanging(string value);
    #endregion
    public Patient()
    {
        _clinicCases = new EntitySet<ClinicCase>(new Action<ClinicCase>(this.ClinicCases_Attach), new Action<ClinicCase>(this.ClinicCases_Detach));
        _patientsAddresses = new EntitySet<PatientAddress>(new Action<PatientAddress>(this.PatientsAddresses_Attach), new Action<PatientAddress>(this.PatientsAddresses_Detach));
        _patientsPhoneNumbers = new EntitySet<PatientPhoneNumber>(new Action<PatientPhoneNumber>(this.PatientsPhoneNumbers_Attach), new Action<PatientPhoneNumber>(this.PatientsPhoneNumbers_Detach));
        this.OnCreated();
    }
    [Column(Storage="_birthday", Name="Birthday", DbType="integer", AutoSync=AutoSync.Never, CanBeNull=false)]
    [DebuggerNonUserCode()]
    public long BirthdayBinaryDate
    {
        get
        {
            return this._birthday;
        }
        set
        {
            if ((_birthday != value))
            {
                this.OnBirthdayChanging(value);
                this.SendPropertyChanging();
                this._birthday = value;
                this.SendPropertyChanged("Birthday");
                this.OnBirthdayChanged();
            }
        }
    }
    [Column(Storage="_firstName", Name="FirstName", DbType="text", AutoSync=AutoSync.Never, CanBeNull=false)]
    [DebuggerNonUserCode()]
    public string FirstName
    {
        get
        {
            return this._firstName;
        }
        set
        {
            if (((_firstName == value) 
                        == false))
            {
                this.OnFirstNameChanging(value);
                this.SendPropertyChanging();
                this._firstName = value;
                this.SendPropertyChanged("FirstName");
                this.OnFirstNameChanged();
            }
        }
    }
    [Column(Storage="_hasChildren", Name="HasChildren", DbType="integer", AutoSync=AutoSync.Never, CanBeNull=false)]
    [DebuggerNonUserCode()]
    public int HasChildren
    {
        get
        {
            return this._hasChildren;
        }
        set
        {
            if ((_hasChildren != value))
            {
                this.OnHasChildrenChanging(value);
                this.SendPropertyChanging();
                this._hasChildren = value;
                this.SendPropertyChanged("HasChildren");
                this.OnHasChildrenChanged();
            }
        }
    }
    [Column(Storage="_id", Name="ID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)]
    [DebuggerNonUserCode()]
    public System.Nullable<int> ID
    {
        get
        {
            return this._id;
        }
        set
        {
            if ((_id != value))
            {
                this.OnIDChanging(value);
                this.SendPropertyChanging();
                this._id = value;
                this.SendPropertyChanged("ID");
                this.OnIDChanged();
            }
        }
    }
    [Column(Storage="_isMarried", Name="IsMarried", DbType="integer", AutoSync=AutoSync.Never, CanBeNull=false)]
    [DebuggerNonUserCode()]
    public int IsMarried
    {
        get
        {
            return this._isMarried;
        }
        set
        {
            if ((_isMarried != value))
            {
                this.OnIsMarriedChanging(value);
                this.SendPropertyChanging();
                this._isMarried = value;
                this.SendPropertyChanged("IsMarried");
                this.OnIsMarriedChanged();
            }
        }
    }
    [Column(Storage="_lastName", Name="LastName", DbType="text", AutoSync=AutoSync.Never, CanBeNull=false)]
    [DebuggerNonUserCode()]
    public string LastName
    {
        get
        {
            return this._lastName;
        }
        set
        {
            if (((_lastName == value) 
                        == false))
            {
                this.OnLastNameChanging(value);
                this.SendPropertyChanging();
                this._lastName = value;
                this.SendPropertyChanged("LastName");
                this.OnLastNameChanged();
            }
        }
    }
    [Column(Storage="_profession", Name="Profession", DbType="text", AutoSync=AutoSync.Never)]
    [DebuggerNonUserCode()]
    public string Profession
    {
        get
        {
            return this._profession;
        }
        set
        {
            if (((_profession == value) 
                        == false))
            {
                this.OnProfessionChanging(value);
                this.SendPropertyChanging();
                this._profession = value;
                this.SendPropertyChanged("Profession");
                this.OnProfessionChanged();
            }
        }
    }
    #region Children
    [Association(Storage="_clinicCases", OtherKey="PatientID", ThisKey="ID", Name="fk_ClinicCases_0")]
    [DebuggerNonUserCode()]
    public EntitySet<ClinicCase> ClinicCases
    {
        get
        {
            return this._clinicCases;
        }
        set
        {
            this._clinicCases = value;
        }
    }
    [Association(Storage="_patientsAddresses", OtherKey="PatientID", ThisKey="ID", Name="fk_PatientsAddresses_0")]
    [DebuggerNonUserCode()]
    public EntitySet<PatientAddress> Addresses
    {
        get
        {
            return this._patientsAddresses;
        }
        set
        {
            this._patientsAddresses = value;
        }
    }
    [Association(Storage="_patientsPhoneNumbers", OtherKey="PatientID", ThisKey="ID", Name="fk_PatientsPhoneNumbers_0")]
    [DebuggerNonUserCode()]
    public EntitySet<PatientPhoneNumber> PhoneNumbers
    {
        get
        {
            return this._patientsPhoneNumbers;
        }
        set
        {
            this._patientsPhoneNumbers = value;
        }
    }
    #endregion
    public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging;
    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    protected virtual void SendPropertyChanging()
    {
        System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging;
        if ((h != null))
        {
            h(this, emptyChangingEventArgs);
        }
    }
    protected virtual void SendPropertyChanged(string propertyName)
    {
        System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged;
        if ((h != null))
        {
            h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
    #region Attachment handlers
    private void ClinicCases_Attach(ClinicCase entity)
    {
        this.SendPropertyChanging();
        entity.Patient = this;
    }
    private void ClinicCases_Detach(ClinicCase entity)
    {
        this.SendPropertyChanging();
        entity.Patient = null;
    }
    private void PatientsAddresses_Attach(PatientAddress entity)
    {
        this.SendPropertyChanging();
        entity.Patient = this;
    }
    private void PatientsAddresses_Detach(PatientAddress entity)
    {
        this.SendPropertyChanging();
        entity.Patient = null;
    }
    private void PatientsPhoneNumbers_Attach(PatientPhoneNumber entity)
    {
        this.SendPropertyChanging();
        entity.Patient = this;
    }
    private void PatientsPhoneNumbers_Detach(PatientPhoneNumber entity)
    {
        this.SendPropertyChanging();
        entity.Patient = null;
    }
    #endregion
}
[Table(Name="main.PatientsAddresses")]
public partial class PatientAddress : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
{
    private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs("");
    private string _address;
    private string _domicileStatus;
    private System.Nullable<int> _patientID;
    private EntityRef<Patient> _patients = new EntityRef<Patient>();
    #region Extensibility Method Declarations
    partial void OnCreated();
    partial void OnAddressChanged();
    partial void OnAddressChanging(string value);
    partial void OnDomicileStatusChanged();
    partial void OnDomicileStatusChanging(string value);
    partial void OnPatientIDChanged();
    partial void OnPatientIDChanging(System.Nullable<int> value);
    #endregion
    public PatientAddress()
    {
        this.OnCreated();
    }
    [Column(Storage="_address", Name="Address", DbType="text", IsPrimaryKey=true, AutoSync=AutoSync.Never)]
    [DebuggerNonUserCode()]
    public string Address
    {
        get
        {
            return this._address;
        }
        set
        {
            if (((_address == value) 
                        == false))
            {
                this.OnAddressChanging(value);
                this.SendPropertyChanging();
                this._address = value;
                this.SendPropertyChanged("Address");
                this.OnAddressChanged();
            }
        }
    }
    [Column(Storage="_domicileStatus", Name="DomicileStatus", DbType="text", AutoSync=AutoSync.Never)]
    [DebuggerNonUserCode()]
    public string DomicileStatus
    {
        get
        {
            return this._domicileStatus;
        }
        set
        {
            if (((_domicileStatus == value) 
                        == false))
            {
                this.OnDomicileStatusChanging(value);
                this.SendPropertyChanging();
                this._domicileStatus = value;
                this.SendPropertyChanged("DomicileStatus");
                this.OnDomicileStatusChanged();
            }
        }
    }
    [Column(Storage="_patientID", Name="PatientID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never)]
    [DebuggerNonUserCode()]
    public System.Nullable<int> PatientID
    {
        get
        {
            return this._patientID;
        }
        set
        {
            if ((_patientID != value))
            {
                if (_patients.HasLoadedOrAssignedValue)
                {
                    throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                }
                this.OnPatientIDChanging(value);
                this.SendPropertyChanging();
                this._patientID = value;
                this.SendPropertyChanged("PatientID");
                this.OnPatientIDChanged();
            }
        }
    }
    #region Parents
    [Association(Storage="_patients", OtherKey="ID", ThisKey="PatientID", Name="fk_PatientsAddresses_0", IsForeignKey=true)]
    [DebuggerNonUserCode()]
    public Patient Patient
    {
        get
        {
            return this._patients.Entity;
        }
        set
        {
            if (((this._patients.Entity == value) 
                        == false))
            {
                if ((this._patients.Entity != null))
                {
                    Patient previousPatients = this._patients.Entity;
                    this._patients.Entity = null;
                    previousPatients.Addresses.Remove(this);
                }
                this._patients.Entity = value;
                if ((value != null))
                {
                    value.Addresses.Add(this);
                    _patientID = value.ID;
                }
                else
                {
                    _patientID = null;
                }
            }
        }
    }
    #endregion
    public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging;
    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    protected virtual void SendPropertyChanging()
    {
        System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging;
        if ((h != null))
        {
            h(this, emptyChangingEventArgs);
        }
    }
    protected virtual void SendPropertyChanged(string propertyName)
    {
        System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged;
        if ((h != null))
        {
            h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}
我使用以下代码向患者添加地址:
PatientAddress address = new PatientAddress();
address.Address = txtAddress.Text;
address.DomicileStatus = cmbDomicileStatus.Text;
currentPatient.Addresses.Add(address);
Database.Source.PatientsAddresses.InsertOnSubmit(address);
Database.Source.SubmitChanges();
Database.Source 是在生成的代码中扩展 DataContext 的类的实例。在 SubmitChanges 上,我收到此异常:
“在 Nullable(Of Int32) 和 Int32 之间未定义相等运算符。”
消息不是逐字报告的,但意思是一样的。堆栈跟踪指向 DbLinq 代码,更准确地说是源文件 DbLinq.Data.Linq.DataContext.cs 的第 709 行。您可以在此处找到源文件:http: //dblinq.codeplex.com/SourceControl/changeset/view/16800#314775(在方法 SetEntityRefQueries(object entity) 的主体下)。我发现问题是在将外键值与表达式树中的常量进行比较时出现的,但我无法获得其他信息。你能帮我找到问题吗?
注意:在调用 SubmitChanges 之前,字段 address.PatientID(外键)实际上设置为正确的值。
 