জেএসএন এবং সত্তার সাথে সার্কুলার রেফারেন্স ইস্যুটি কীভাবে পাবেন


13

আমি এমন একটি ওয়েবসাইট তৈরির পরীক্ষা নিরীক্ষা করছি যা আমার উপস্থাপনা স্তর এবং ডেটা মডেল / ডাটাবেসের জন্য সত্তা কাঠামোর জন্য জেএসওএন সহ এমভিসিকে উপকৃত করে। আমার ইস্যুটি আমার মডেল অবজেক্টগুলিকে জেএসএন-তে সিরিয়ালাইজ করার সাথে খেলতে আসে।

আমি আমার ডাটাবেস তৈরি করতে কোডটি প্রথম পদ্ধতিটি ব্যবহার করছি। কোডটি প্রথম পদ্ধতিটি করার সময় একাধিক সম্পর্কের (পিতা বা মাতা / সন্তানের) সন্তানের প্রয়োজন হয় পিতা-মাতার কাছে ফিরে আসা উচিত। (উদাহরণ কোড আমার টাইপো হতে পারে তবে আপনি ছবিটি পান)

class parent
{
   public List<child> Children{get;set;}
   public int Id{get;set;}

}
class child
{
    public int ParentId{get;set;}
    [ForeignKey("ParentId")]
    public parent MyParent{get;set;}
    public string name{get;set;}
 }

জসনআরসাল্টের মাধ্যমে কোনও "পিতামাতা" অবজেক্ট ফেরত দেওয়ার সময় একটি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্স ত্রুটি নিক্ষেপ করা হয় কারণ "সন্তানের" শ্রেণীর পিতামাতার সম্পত্তি রয়েছে।

আমি স্ক্রিপ্টআইগনোর বৈশিষ্ট্যটি চেষ্টা করেছি তবে আমি শিশুদের বিষয়গুলি দেখার ক্ষমতাটি হারাচ্ছি। আমার কোনও সময়ে পিতামাতাদের সন্তানের দৃশ্যে তথ্য প্রদর্শন করতে হবে।

আমি অভিভাবক এবং সন্তানের উভয়ের জন্য বেস ক্লাস করার চেষ্টা করেছি যার একটি বিজ্ঞপ্তি নেই। দুর্ভাগ্যক্রমে যখন আমি বেসপ্যারেন্ট এবং বেসচিল্ড প্রেরণের চেষ্টা করি তখন এগুলি JSON পার্সার তাদের উদ্ভূত শ্রেণি হিসাবে পড়েন (আমি নিশ্চিত যে এই ধারণাটি আমার থেকে দূরে চলেছে)।

Base.baseParent basep = (Base.baseParent)parent;
return Json(basep, JsonRequestBehavior.AllowGet);

আমি যে সমাধানটি নিয়ে এসেছি তা হ'ল "দেখুন" মডেলগুলি তৈরি করা। আমি ডেটাবেস মডেলগুলির সহজ সংস্করণ তৈরি করি যা পিতাম শ্রেণীর রেফারেন্স অন্তর্ভুক্ত করে না। এই ভিউ মডেলগুলির প্রত্যেকেরই ডাটাবেস সংস্করণ এবং কনস্ট্রাক্টর ফিরিয়ে আনার পদ্ধতি রয়েছে যা ডাটাবেস মডেলটিকে প্যারামিটার হিসাবে নেয় (ভিউমডেল.নাম = ডাটাবেস মডেল.নেম)। যদিও এই পদ্ধতিটি কাজ করে তবে বাধ্য হয়।

দ্রষ্টব্য: আমি এখানে পোস্ট করছি কারণ আমি মনে করি এটি আরও আলোচনার জন্য উপযুক্ত। আমি এই সমস্যাটি দেখতে আসার জন্য একটি ভিন্ন ডিজাইনের প্যাটার্নটি উপার্জন করতে পারি বা এটি আমার মডেলের কোনও আলাদা বৈশিষ্ট্য ব্যবহার করার মতো সহজ হতে পারে। আমার অনুসন্ধানে আমি এই সমস্যাটি কাটিয়ে উঠতে কোনও ভাল পদ্ধতি দেখিনি।

আমার শেষ লক্ষ্যটি হবে একটি দুর্দান্ত এমভিসি অ্যাপ্লিকেশন যা সার্ভারের সাথে যোগাযোগের জন্য এবং ডেটা প্রদর্শনের জন্য জেএসওনকে ভারীভাবে ব্যবহার করে। স্তরগুলি জুড়ে একটি কনসিস্টিটিভ মডেল বজায় রাখার সময় (বা যতটা ভাল আমি আসতে পারি)।

উত্তর:


6

আমি আপনার প্রশ্নে দুটি স্বতন্ত্র বিষয় দেখতে পাচ্ছি:

  • জেএসএনে সিরিয়াল করার সময় বিজ্ঞপ্তি রেফারেন্স কীভাবে পরিচালনা করবেন?
  • আপনার দৃষ্টিভঙ্গিতে মডেল সত্তা হিসাবে EF সত্তাগুলি ব্যবহার করা কতটা নিরাপদ?

বিজ্ঞপ্তি সংক্রান্ত রেফারেন্স সম্পর্কিত আমি দুঃখের সাথে বলছি যে এর কোনও সহজ সমাধান নেই। প্রথম কারণ জেএসওএন নীচের কোডটি বিজ্ঞপ্তি রেফারেন্স উপস্থাপন করতে ব্যবহার করা যাবে না:

var aParent = {Children : []}, aChild  = {Parent : aParent};
aParent.Children.push(aChild);
JSON.stringify(aParent);

ফলাফল স্বরূপ: TypeError: Converting circular structure to JSON

আপনার কাছে কেবল পছন্দটি হ'ল কম্পোজিট -> উপাদানটির রচনাটির অংশ রাখুন এবং "ব্যাক নেভিগেশন" উপাদানটি -> সংমিশ্রণটি ফেলে দিন, সুতরাং আপনার উদাহরণটিতে:

class parent
{
    public List<child> Children{get;set;}
    public int Id{get;set;}
}
class child
{
    public int ParentId{get;set;}
    [ForeignKey("ParentId"), ScriptIgnore]
    public parent MyParent{get;set;}
    public string name{get;set;}
}

এখানে jQuery ব্যবহার করে আপনার ক্লায়েন্ট পক্ষের এই নেভিগেশন সম্পত্তি পুনরায় রচনা করতে আপনাকে কোনও কিছুই বাধা দেয় না:

$.each(parent.Children, function(i, child) {
  child.Parent = parent;  
})

তবে তারপরে আপনাকে এটি আবার সার্ভারে প্রেরণের আগে তা আবার ফেলে দিতে হবে, কারণ জেএসওএন। স্ট্রিংফাইটি বিজ্ঞপ্তি রেফারেন্সটি সিরিয়াল করতে সক্ষম হবে না:

$.each(parent.Children, function(i, child) {
  delete child.Parent;  
})

এখন EF সত্তাগুলি আপনার ভিউ মডেল সত্তা হিসাবে ব্যবহার করার বিষয়টি রয়েছে।

প্রথম EF সম্ভবত আপনার সনাক্তকরণ বা অলস লোডিংয়ের মতো আচরণগুলি বাস্তবায়নের জন্য আপনার শ্রেণীর ডায়নামিক প্রক্সি ব্যবহার করতে পারে, আপনি যদি EF সত্ত্বাগুলি সিরিয়াল করতে চান তবে আপনাকে সেগুলি অক্ষম করতে হবে।

এছাড়াও ইউআইতে ইএফ সত্তা ব্যবহার করা ঝুঁকিপূর্ণ হতে পারে যেহেতু সমস্ত ডিফল্ট বাইন্ডার প্রতিটি ক্ষেত্র ম্যাপিংয়ের জন্য অনুরোধ থেকে সত্তার ক্ষেত্রগুলিতে ম্যাপিং করবে যা আপনি চান না যে ব্যবহারকারী সেট করতে পারে।

সুতরাং, আপনি যদি চান এমভিসি অ্যাপ্লিকেশনটি সঠিকভাবে ডিজাইন করা হোক তবে আমি আপনার অভ্যন্তরীণ ব্যবসায়ের মডেলগুলির "সাহস" ক্লায়েন্টের সংস্পর্শে আসার হাত থেকে বাঁচাতে একটি উত্সর্গীকৃত ভিউ মডেল ব্যবহার করার পরামর্শ দেব, সুতরাং আমি আপনাকে একটি নির্দিষ্ট ভিউ মডেলের প্রস্তাব দেব।


অবজেক্ট ওরিয়েন্টেড কৌশলগুলির সাথে কি অভিনব উপায় আছে যা আমি বিজ্ঞপ্তি রেফারেন্স এবং ইএফ ইস্যু উভয়ই পেতে পারি।
ড্যানস্ক্যান

সার্কুলার রেফারেন্স এবং EF ইস্যু উভয়ই পেতে পারি অবজেক্ট ওরিয়েন্টেড কৌশলগুলির সাথে কি অভিনব উপায় আছে? বেসওজেক্ট যেমন ইন্টিওজেক্ট এবং ভিউজেক্ট দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত। সুতরাং ইন্টিওবজেক্টের সাথে বিজ্ঞপ্তিযুক্ত রেফারেন্স থাকবে তবে ভিউবজেক্টের সাথে বিজ্ঞপ্তিটির রেফারেন্স থাকবে না। আমি এটিটি অবজেক্টটি অ্যান্টিওজেক্ট (ভিউওজেক্ট.নেম = অ্যান্টিওজেক্ট.নেম) থেকে বিল্ডিংয়ের মাধ্যমে পেয়েছি তবে এটি সময়ের অপচয় বলে মনে হচ্ছে। আমি কীভাবে এই সমস্যাটি পেতে পারি?
ড্যানস্ক্যান

তারা আপনি খুব । আপনার ব্যাখ্যাটি খুব স্পষ্ট এবং বোঝা সহজ ছিল।
নিক

2

বস্তুগুলিকে সিরিয়ালাইজ করার চেষ্টা করার একটি সহজ বিকল্প হ'ল পিতামাতা / শিশু অবজেক্টের সিরিয়ালাইজেশন অক্ষম করা। পরিবর্তে, সম্পর্কিত পিতামাতার / শিশুদের যখন আপনার প্রয়োজন হিসাবে আনতে আলাদা কল করতে পারেন call এটি আপনার আবেদনের জন্য আদর্শ নাও হতে পারে তবে এটি একটি বিকল্প।

এটি করার জন্য, আপনি একটি ডেটা কন্ট্রাক্টসরিয়ালাইজার সেট আপ করতে এবং আপনার ডেটা মডেল ক্লাসের কনস্ট্রাক্টরে ডেটা কন্ট্রাক্টসরিয়ালাইজার সেট করতে পারেন O এটি নির্দিষ্ট করে যে এইচটিটিপি প্রতিক্রিয়াগুলিকে সিরিয়ালাইজ করার সময় অবজেক্টের রেফারেন্সগুলি সংরক্ষণ করা উচিত নয়।

উদাহরণ:

জসন ফর্ম্যাট:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = 
    Newtonsoft.Json.PreserveReferencesHandling.None;

এক্সএমএল ফর্ম্যাট:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
var dcs = new DataContractSerializer(typeof(Employee), null, int.MaxValue, 
    false, /* preserveObjectReferences: */ false, null);
xml.SetSerializer<Employee>(dcs);

এর অর্থ হ'ল আপনি যদি এমন কোনও আইটেম নিয়ে থাকেন যা শিশু অবজেক্টস রেফারেন্স করে থাকে তবে শিশু অবজেক্টগুলি সিরিয়ালাইজ করা হবে না।

ডেটা কন্ট্রাক্টসরিয়ালাইজার ক্লাসটিও দেখুন ।


1

জেএসএন সিরিয়ালাইজার যা বিজ্ঞপ্তি রেফারেন্সগুলি নিয়ে কাজ করে

এখানে কাস্টম জ্যাকসনের একটি উদাহরণ রয়েছে JSONSerializerযা প্রথম ঘটনাকে সিরিয়ালাইজ করে এবং referenceপরবর্তী সমস্ত ঘটনার উপর একটি * প্রথম ঘটনাতে সংরক্ষণ করে বৃত্তাকার রেফারেন্সের সাথে সম্পর্কিত হয় ।

জ্যাকসনের সাথে বস্তুগুলিকে সিরিয়াল করার সময় বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সের সাথে কাজ করা

উপরের নিবন্ধ থেকে প্রাসঙ্গিক আংশিক স্নিপেট:

private final Set<ObjectName> seen;

/**
 * Serialize an ObjectName with all its attributes or only its String representation if it is a circular reference.
 * @param on ObjectName to serialize
 * @param jgen JsonGenerator to build the output
 * @param provider SerializerProvider
 * @throws IOException
 * @throws JsonProcessingException
 */
@Override
public void serialize(@Nonnull final ObjectName on, @Nonnull final JsonGenerator jgen, @Nonnull final SerializerProvider provider) throws IOException, JsonProcessingException
{
    if (this.seen.contains(on))
    {
        jgen.writeString(on.toString());
    }
    else
    {
        this.seen.add(on);
        jgen.writeStartObject();
        final List<MBeanAttributeInfo> ais = this.getAttributeInfos(on);
        for (final MBeanAttributeInfo ai : ais)
        {
            final Object attribute = this.getAttribute(on, ai.getName());
            jgen.writeObjectField(ai.getName(), attribute);
        }
        jgen.writeEndObject();
    }
}

0

আমি যে সমাধানটি নিয়ে এসেছি তা হ'ল "দেখুন" মডেলগুলি তৈরি করা। আমি ডেটাবেস মডেলগুলির সহজ সংস্করণ তৈরি করি যা পিতাম শ্রেণীর রেফারেন্স অন্তর্ভুক্ত করে না। এই ভিউ মডেলগুলির প্রত্যেকেরই ডাটাবেস সংস্করণ এবং কনস্ট্রাক্টর ফিরিয়ে আনার পদ্ধতি রয়েছে যা ডাটাবেস মডেলটিকে প্যারামিটার হিসাবে নেয় (ভিউমডেল.নাম = ডাটাবেস মডেল.নেম)। যদিও এই পদ্ধতিটি কাজ করে তবে বাধ্য হয়।

খালি ন্যূনতম ডেটা পাঠানো একমাত্র সঠিক উত্তর। আপনি যখন ডাটাবেস থেকে ডেটা প্রেরণ করেন, সাধারণত সমস্ত অ্যাসোসিয়েশনের সাথে প্রতিটি একক কলাম প্রেরণ করার কোনও অর্থ হয় না। গ্রাহকদের ডাটাবেস সমিতি এবং কাঠামো, যে ডাটাবেসগুলির জন্য ডিল করার প্রয়োজন নেই। এটি কেবল ব্যান্ডউইথকেই সাশ্রয় করবে না এটি বজায় রাখা, পড়া এবং গ্রহন করাও অনেক সহজ। ডেটা জিজ্ঞাসা করুন এবং তারপরে আপনার eq প্রেরণের জন্য যা প্রয়োজন তা মডেল করুন। খালি সর্বনিম্ন।


আপনি যখন বড় ডেটার কথা বলছেন তখন আরও প্রক্রিয়াকরণের সময় প্রয়োজন, এখন যেমন আপনাকে দু'বার করে সবকিছু রূপান্তর করতে হবে।
ডেভিড ভ্যান দুগ্তেরেন

-2

.Include(x => x.TableName ) সম্পর্কের প্রত্যাবর্তন (প্রধান টেবিল থেকে নির্ভর টেবিল থেকে) না পৌঁছানো, বা কেবলমাত্র এক সারি ডেটা ফেরানো, এখানে ফিক্স করুন:

/programming/43127957/include-not-working-in-net-core-returns-one-parent

এছাড়াও, স্টার্টআপ.সগুলিতে নিশ্চিত করুন যে আপনার এটি শীর্ষে রয়েছে:

using Microsoft.EntityFrameworkCore; 
using Newtonsoft.Json; 
using Project_Name_Here.Models;

পুত্র ওয়াট? এরম .. ওয়াট?
আমেলস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.