تطبيقات متعددة المستويات باستخدام L2S و WCF والفئة الأساسية
-
27-09-2019 - |
سؤال
في يوم من الأيام قررت إنشاء هذا التطبيق متعدد المستويات باستخدام L2S و WCF. النموذج المبسط هو: Database-> L2S-> Wrapper (DTO)-> تطبيق العميل. يتم تحقيق الاتصال بين العميل وقاعدة البيانات باستخدام كائنات نقل البيانات التي تحتوي على كائنات كيان كخصائصها.
abstract public class BaseObject
{
public virtual IccSystem.iccObjectTypes ObjectICC_Type
{
get { return IccSystem.iccObjectTypes.unknownType; }
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_ID", AutoSync = AutoSync.OnInsert, DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
[global::System.Runtime.Serialization.DataMemberAttribute(Order = 1)]
public virtual long ID
{
//get;
//set;
get
{
return _ID;
}
set
{
_ID = value;
}
}
}
[DataContract]
public class BaseObjectWrapper<T> where T : BaseObject
{
#region Fields
private T _DBObject;
#endregion
#region Properties
[DataMember]
public T Entity
{
get { return _DBObject; }
set { _DBObject = value; }
}
#endregion
}
بسيط جدا ، أليس كذلك؟. ها هي الصيد. تحتوي كل واحدة من الفئات المعينة على خاصية ID نفسها ، لذا قررت تجاوزها مثل هذا
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Divisions")]
[global::System.Runtime.Serialization.DataContractAttribute()]
public partial class Division : INotifyPropertyChanging, INotifyPropertyChanged
{
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="BigInt NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
[global::System.Runtime.Serialization.DataMemberAttribute(Order=1)]
public override long ID
{
get
{
return this._ID;
}
set
{
if ((this._ID != value))
{
this.OnIDChanging(value);
this.SendPropertyChanging();
this._ID = value;
this.SendPropertyChanged("ID");
this.OnIDChanged();
}
}
}
}
غلاف للقسمة واضح ومباشر أيضًا:
public class DivisionWrapper : BaseObjectWrapper<Division>
{
}
لقد عملت بشكل جيد طالما ظللت قيم المعرف في الفصل المعني وفئة BaseObject الخاصة بها (هذا ليس مقاربة جيدة جدًا ، وأنا أعلم ، ولكن بعد ذلك حدث: حدث ذلك:
private CentralDC _dc;
public bool UpdateDivision(ref DivisionWrapper division)
{
DivisionWrapper tempWrapper = division;
if (division.Entity == null)
{
return false;
}
try
{
Table<Division> table = _dc.Divisions;
var q = table.Where(o => o.ID == tempWrapper.Entity.ID);
if (q.Count() == 0)
{
division.Entity._errorMessage = "Unable to locate entity with id " + division.Entity.ID.ToString();
return false;
}
var realEntity = q.First();
realEntity = division.Entity;
_dc.SubmitChanges();
return true;
}
catch (Exception ex)
{
division.Entity._errorMessage = ex.Message;
return false;
}
}
عند محاولة التعداد عبر الاستعلام في الذاكرة ، حدث الاستثناء التالي: أعضاء الفئة BASEOBJECT.ID غير محفوظ. على الرغم من أنني أذكر النوع وإلغاء خاصية ID L2S فشل في العمل. أي اقتراحات؟
المحلول
افترض أنني وجدت المشكلة. عند الكتابة
var q = table.Where(o => o.ID == tempWrapper.Entity.ID);
يشير المترجم إلى أن الكائن من نوع BaseObject وبالتالي يحاول الحصول على قيمة المعرف الخاصة به من تعيين BaseObject وأنه غير محفور. يبدو أن المشكلة يتم حلها من خلال الإعلان صراحةً النوع:
var q = from Division div in _dc.GetTable<Division>()
where div.ID == tempWrapper.Entity.ID
select div;