سؤال

مستودع الخاص بي لديه List<Student>, List<Course> و List<Enrolment> عندما يكون للتسجيل إلغاؤه عدلا إلغالاين .النفسان والتحال في المراجع التي تشير إلى إحدى الطلاب أو الدورات في القوائمتين السابقة.

عندما أستخدم Xmlserializer على مستودعي، فإنه يخرج البيانات الزائدة عند تسليم جميع خصائص كل طالب List<Student> ثم مرة أخرى لكل إشارة إلى نفس الطلاب في List<Enrolment>. وبعد أنا أبحث عن طريقة أنيقة لحل هذا.

بعد التحيز، يمكنني إصلاح المراجع باستخدام قيم المعرف في مثيلات الكائنات المكررة التي تم إنشاؤها بواسطة التحمل ولكن يبدو هذا اختراقا.

إحدى الطرق لإصلاح الإخراج المكرر هو إلغاء حدوث Xmlignore.student وإدارته وإنشاء خصائصا أخرى للمسلعة - إلتحقان إلغاء الاستخدام. ومع ذلك، أثناء التحيز، لا يمكن تعيين المراجع الخاصة بالالتحضن والالتحاق. List<Student> و List<Course> غير متوفرة.

طريقة أخرى فكرتت في التسلسل المنخفض في التسلسل الهرمي للكائن التي تقوم بكل قوائم بي بشكل منفصل والتحكم في ترتيب التحيز - أنا بدلا من عدم القيام بذلك.

سوف تكون طريقة أخرى إلى xmlignore List<Enrolment> وإنشاء فئة مساعد تسلسل التسجيل التي تهيئة List<Enrolment> بعد هزيمة نفسها كاملة. هذا يبدو وكأنه الكثير من الجهد.

كيف يقوم أشخاص آخرون بتسلسل / تخليص مراجع متعددة إلى نفس الكائن باستخدام XMLSerializer؟

هل كانت مفيدة؟

المحلول

يا آلام التسلسل: -> ...

لم يكن هناك حل عام لهذا الأمر، أعتقد أن هذا هو السبب في جرافة MS من إطار Silverlight.

لا أعتمد أبدا على أي آليات تسلسل تلقائية لإطار .NET Framework. بالنسبة للنماذج الخاصة بي والمستودعات الخاصة بي، عادة ما أعرف أو يمكنها عادة تحديد الخصائص التي تعد برمجيا هي تلك العددية البسيطة (أرقام / سلاسل / إلخ) والتي هي روابط إلى كائنات أخرى (وكذلك قوائم إما).

هناك أساسا 2 سيناريوهات:

1: نريد تسلسل / نقل فقط المعلومات المسطحة من الكائنات. في هذه الحالة، أقوم بنقل المعرفات المعنية فقط للخصائص التي تصل إلى كائنات أخرى. يمكن للمستقبل بعد ذلك إجراء استفسارات لاحقة للحصول على جميع الكائنات الأخرى التي يحتاجونها.

2: نريد نقل أكبر قدر ممكن من المعلومات، أي أعمق متداخلة XML مع عدة مستويات، ومعظمها بالنسبة لمعظم وظيفة التقارير التي تعرض كل شيء مباشرة باستخدام بعض CSS فقط على XML. في هذه الحالة، من المرغوب فيه بالفعل أن الكائنات التي هي نفسها سيتم حلها عدة مرات في شجرة XML.

في بعض الأحيان أحتاج إلى تعديل السيناريو الأول قليلا من أجل تجنب الكثير من مكالمات الاستعلام اللاحقة، ولكن عادة ما أحصل على مستوى جيد للغاية. أي لقد قمت بنيت في قاعدة التعليمات البرمجية التي يمكننا تحديد الأشياء الإضافية التي نريد حلها عند و / أو تكوينها في مكان ما.

نصائح أخرى

لا يوجد حل لهذه المشكلة باستخدام Serializer XML. ليس لديه مفهوم الهوية التي قد تستخدمها لإزالة الازدواجية.

أفضل ما يمكنك القيام به هو تسلسل مجموعة الكائنات بشكل منفصل عن مراجعها. ثم يمكنك إعادة إنشاء قوائمك بعد التحيز.

راجع للشغل، هل تدرك أن Xmlserializer غير محددة ل C #؟

يمكنك تطبيق واجهة IXMLSerialialialialiable للتسجيل وفي طريقة WriteXML تولد الطالب والدورة XML التي ستتضمن مفاتيح فقط على سبيل المثال:

<Student Id="5"/>
<Course Id="6"/>

وفي طريقة ReadXML، يمكنك تحميل المراجع من هذا. يجب عليك أيضا تعيين سمة Xmlignore إلى خاصية الطالب والطبع.

كيف هذا الصوت كحل:

  1. Xmlignore كل مرجع ثانوي أي إلتحقان.
  2. قم بإنشاء خاصية لكل مرجع ثانوي يستخدم لتسليط / التحيز بمفتاح أجنبي لهذا المرجع بدلا من ذلك - بادئة مع XML_FK. على سبيل المثال xml_fk_student & xml_fk_course
  3. قم بإنشاء طريقة XML_Finalizedeserialization التي يتم استدعاؤها بعد التحيز لتحميل المراجع باستخدام تلك الخصائص الرئيسية الأجنبية.

يجب / يمكنك استخدام التتبع المرجعي باستخدام Serializer DataContract:

//deserilaize:
using(MemoryStream memStmBack = new MemoryStream()) {
  var serializerForth = new DataContractSerializer(
    typeof(YourType),
    null,
    0x7FFF /*maxItemsInObjectGraph*/ ,
    false /*ignoreExtensionDataObject*/ ,
    true /*preserveObjectReferences*/ ,
    null /*dataContractSurrogate*/ );

  byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
  memStmBack.Write(data, 0, data.Length);
  memStmBack.Position = 0;
  var lsBack = (YourType) serializerForth.ReadObject(memStmBack);

}
//serialize...
using(MemoryStream memStm = new MemoryStream()) {
    var serializer = new DataContractSerializer(
      typeof(YourType),
      knownTypes,
      0x7FFF /*maxItemsInObjectGraph*/ ,
      false /*ignoreExtensionDataObject*/ ,
      true /*preserveObjectReferences*/ ,
      null /*dataContractSurrogate*/ );

    serializer.WriteObject(memStm, yourType);

    memStm.Seek(0, SeekOrigin.Begin);

    using(var streamReader = new StreamReader(memStm)) {
        result = streamReader.ReadToEnd();

او استعمل

[Serializable]
[DataContract(IsReference = true)]
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top