1. এন্টিটি এবং অ্যাসোসিয়েশনের মৌলিক ধারণা

এন্টি ফ্রেমওয়ার্কে, এন্টিটি বাসস্বতভাবে ডাটাবেসে ম্যানেজ করা মৌলিক ডেটা ইউনিট পরিপালিত করে, যা সাধারণত ডাটাবেসের একটি টেবিলের সাথে সামঞ্জস্যপূর্ণ। এন্টিটির মধ্যে ফিল্ডগুলি টেবিলের কলামের সাথে সামঞ্জস্যপূর্ণ হয়, যা এন্টিটির মধ্যে অ্যাসোসিয়েশন (এজ) - গুলি ব্যবহার করে এন্টিটির মধ্যে সম্পর্ক ও অবলম্ব বর্ণনা করতে ব্যবহৃত হয়। এন্টিটি অ্যাসোসিয়েশন জাড় ডেটা মডেল গঠনের জন্য মৌলিক জাড়, যা প্যারেন্ট-চাইল্ড সম্পর্ক এবং মালিকানা সম্পর্কের মতন হায়ারকিয়াল সম্পর্ক প্রতিনিধিত্ব করার জন্য অনুমতি দেয়।

এন্টি ফ্রেমওয়ার্কটি এই অ্যাসোসিয়েশনগুলি ডিফাইন এবং পরিচালনা করার জন্য একটি ধামসিক অ্যাপিতের ধরায় শক্তিশালী সেট প্রদান করে। এই অ্যাসোসিয়েশনগুলির মাধ্যমে, আমরা সহজেই ডেটা মধ্যে জটিল ব্যবসায়িক লজিক প্রকাশ এবং পরিচালনা করতে পারি।

2. ent এ এন্টিটি অ্যাসোসিয়েশনের প্রকার

2.1 এক-থেকে-এক (O2O) অ্যাসোসিয়েশন

এক-থেকে-এক অ্যাসোসিয়েশনে দুটি এন্টিটির মধ্যে এক-থেকে-এক সামঞ্জস্যপূর্ণ সম্পর্ক উল্লেখ করে। উদাহরণস্বরূপ, ব্যবহারকারী এবং ব্যাংক হিসাবের মিশরণ মনে করুন, প্রতিটি ব্যবহারকারীর একটি ব্যাংক হিসাব থাকতে পারে, এবং প্রতিটি ব্যাংক হিসাবও শুধুমাত্র একটি ব্যবহারকারীর মালিক। এন্টি ফ্রেমওয়ার্কটি edge.To এবং edge.From মেথড ব্যবহার করে এমন অ্যাসোসিয়েশন সংজ্ঞায়িত করতে।

প্রথমে, আমরা User স্কিমা অংশে Card এ পয়েন্টিং করা এক-থেকে-এক অ্যাসোসিয়েশন সংজ্ঞায়িত করতে পারি:

// User এর এজ.
func (User) Edges() []ent.Edge {
    return []ent.Edge{
        edge.To("card", Card.Type). // কার্ড এন্টিটির দিকে পয়েন্ট করে, অ্যাসোসিয়েশনের নামকে "কার্ড" হিসেবে সংজ্ঞায়িত করতে
            Unique(),               // ইউনিক মেথড এইটি এক-থেকে-এক অ্যাসোসিয়েশন হিসেবে নিশ্চিত করে
    }
}

পরবর্তীতে, আমরা Card স্কিমা অংশে User এ প্লবর্তী অ্যাসোসিয়েশন ব্যাক ডিফাইন করতে পারি:

// কার্ডের এজ.
func (Card) Edges() []ent.Edge {
    return []ent.Edge{
        edge.From("owner", User.Type). // কার্ড থেকে ইউজারে নির্দিষ্ট ভাবে যাওয়া হয়, অ্যাসোসিয়েশনের নামকে "মালিক" হিসেবে সাংজ্ঞায়িত করা হয়
            Ref("card").              // টিকে দেয় প্রতিবিম্বন অ্যাসোসিয়েশনের নাম
            Unique(),                 // একটি মার্ক ব্যবহার করে নিশ্চিত করা হয়েছে যে একটি কার্ড একটি মালিকের সাথে মিলে
    }
}

2.2 এক-থেকে-অনেক (O2M) অ্যাসোসিয়েশন

এক-থেকে-অনেক অ্যাসোসিয়েশন নির্দেশ করে যে একটি এন্টিটি বেশি অন্যান্য এন্টিটিগুলির সাথে সংমিলিত হতে পারে, কিন্তু এই সমস্যা গুলির প্রতিটি এন্টিটির জন্য একটি এন্টিটিতে পৌছাতে পারে। উদাহরণস্বরূপ, একটি ব্যবহারকারীর অনেকগুলি প্যারেন্ট থাকতে পারে, কিন্তু প্রতিটি লেখা শুধুমাত্র একজন মালিক থাকতে পারে।

এন্টি এখানেই এই ধরণের এসোসিয়েশন সংজ্ঞায়িত করতে edge.To এবং edge.From ব্যবহার করি। নীচের উদাহরণ এখানে ব্যবহারকারী ও পোষ্টাগুলির মধ্যে এক-থেকে-অনেক অ্যাসোসিয়েশন সংজ্ঞায়িত করে:

// ইজ অফ দি উজার.
func (User) Edges() []ent.Edge {
    return []ent.Edge{
        edge.To("pets", Pet.Type), // ব্যবহারকারী এন্টিটি থেকে পেট এন্টিটির এক-থেকে-অনেক অ্যাসোসিয়েশন
    }
}

Pet এন্টিটির মধ্যে, আমরা User এতে প্লবর্তী এন্টিটির জন্য এক অ্যাসোসিয়েশন ব্যবহার করি:

// পেটের এজ.
func (Pet) Edges() []ent.Edge {
    return []ent.Edge{
        edge.From("owner", User.Type). // পেট থেকে ব্যবহারকারীগুলির জন্য এক-থেকে-অনেক অ্যাসোসিয়েশন
            Ref("pets").               // পেট থেকে মালিকের প্রতিবিম্বতা অ্যাসোসিয়েশনের নাম নির্দিষ্ট করে
            Unique(),                  // নিশ্চিত করতে একটি মার্ক ব্যবহার করে যে একটি মালিকের অনেকগুলি পেট থাকতে পারে
    }
}

2.3 অনেক-থেকে-অনেক (M2M) অ্যাসোসিয়েশন

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

Student এন্টিটির মধ্যে, আমরা Course এর সাথে অনেক-থেকে-অনেক অ্যাসোসিয়েশন স্থাপন করতে edge.To ব্যবহার করি:

// ছাত্র এজ.
func (Student) Edges() []ent.Edge {
    return []ent.Edge{
        edge.To("courses", Course.Type), // ছাত্র এডগুলি থেকে কোর্স এন্টিটির অনেক-থেকে-অনেক অ্যাসোসিয়েশন সংজ্ঞায়িত করে
    }
}

3. Entity Associations এর জন্য বিশিষ্ট কাজ

এই অধ্যায়টি বিবেচনা করবে কীভাবে ইন্ট ব্যবহার করে ডিফাইনড সম্পর্কগুলির সাথে বিভিন্ন বেসিক অপারেশন পারসোনাল করতে হয়, যেমন এন্টিটি তৈরি, কুয়েরি, এবং সংশ্লিষ্ট এন্টিটি অতিক্রম করা।

3.1 এসোসিয়েটেড এন্টিটি তৈরি করা

এন্টিটি তৈরি করতে সময়, আপনি এন্টিটি মধ্যে সম্পর্কগুলি একই সাথে সেট করতে পারেন। O2M (এক থেকে বহু) এবং M2M (বহু থেকে বহু) সম্পর্কের জন্য, আপনি অ্যাসোসিয়েটেড এন্টিটিগুলি যোগ করতে Add{Edge} মেথড ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, আমাদের যদি একটি ব্যবহারকারী এন্টিটি এবং একটি পেট এন্টিটি থাকে এবং একটি নির্দিষ্ট যৌথপ্রসঙ্গের সাথে সংস্থাপন থাকে, যেখানে একজন ব্যবহারকারীর প্রাপ্তি অনেকগুলি প্রাণীর মালিক হতে পারে, তাহলে নীচের উদাহরণটি একটি নতুন ব্যবহারকারী তৈরি এবং তাদের জন্য পেটগুলি যোগ করার একটি উদাহরণ:

// ব্যবহারকারী তৈরি করুন এবং পেট যুক্ত করুন
func CreateUserWithPets(ctx context.Context, client *ent.Client) (*ent.User, error) {
    // একটি পেট ইনস্ট্যান্স তৈরি করুন
    fido := client.Pet.
        Create().  
        SetName("Fido").
        SaveX(ctx)
    // একটি ব্যবহারকারী ইনস্ট্যান্স তৈরি করুন এবং এটি পেটের সাথে যুক্ত করুন
    user := client.User.
        Create().
        SetName("Alice").
        AddPets(fido). // পেট যুক্ত করতে AddPets মেথডটি ব্যবহার করুন
        SaveX(ctx)

    return user, nil
}

এই উদাহরণে, প্রথমে আমরা প্রাণীর একটি প্রতিষ্ঠান Fido তৈরি করি, তারপরে Alice নামের ব্যবহারকারী তৈরি করি এবং AddPets মেথড ব্যবহার করে প্রতিষ্ঠানের সাথে প্রাণী সংযুক্ত করি।

3.2 এসোসিএটেড এন্টিটি ক্যুয়ারি

এসোসিএটেড এন্টিটি কুয়েরি করা হল একটি সাধারণ অপারেশন ইস্যান্ট এ। উদাহরণস্বরূপ, আপনি ব্যবহার করতে পারেন Query{Edge} মেথডটি ব্যবহার করে নির্দিষ্ট এন্টিটির সাথে সংস্থিত অন্যান্য এন্টিটি প্রাপ্ত করবেন।

ব্যবহারকারী এবং প্রাণীর উদাহরণে অনুযায়ী পরিচালনা করবেন নিম্নলিখিত প্রাণী গুলি যার ধনী একজন ব্যবহারকারীর মালিক।

// একটি ব্যবহারকারীর সমস্ত প্রাণীর ক্যুয়ারি
func QueryUserPets(ctx context.Context, client *ent.Client, userID int) ([]*ent.Pet, error) {
    pets, err := client.User.
        Get(ctx, userID). // ব্যবহারকারী আইডি অনুযায়ী ব্যবহারকারী ইনস্ট্যান্স পান
        QueryPets().      // ব্যবহারকারীর সঙ্গে সংস্থিত প্রাণী এন্টিটি কুয়েরী
        All(ctx)          // ক্যুয়েরীকৃত সমস্ত প্রাণী এন্টিটি ফিরিয়ে দিন
    if err != nil {
        return nil, err
    }

    return pets, nil
}

উপরের কোড টুকড়েশি অংশে, আমরা প্রথমে ব্যবহারকারী ইনস্ট্যান্সটি ব্যবহারকারী আইডি অনুযায়ী পেতে, তারপরে QueryPets মেথডটি ব্যবহার করে প্রাণী এন্টিটি সংস্থিত করি।

দ্রষ্টব্য: ইন্ট এর কোড জেনারেশন টুল স্বয়ংক্রিয়ভাবে সংক্ষিপ্ত অনুসরণ বাধ্যতামূলক তথ্যর অনুসরণ করে সংস্থিত অনুসরণার জন্য API নির্মাণ করে। উপরে উন্নীত কোড পর্যালোচনা করা উচিত।

4. ইগার লোডিং

4.1 প্রিলোডিং এর নীতিগুলি

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

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

4.2 প্রিলোডিং এর অনুমান

আমরা এখন নমুনা কোড ব্যবহার করে এন্ট ফ্রেমওয়ার্কে প্রিলোড অপারেশন পরিচালনা করার জন্য কিভাবে পরিচালিত করতে হয় তা প্রদর্শন করব। এর সংঘাতাত্মক ফর্ম উপরে প্রকতিকরণে জন্য ব্যবহৃত ব্যক্তি-প্রাণীর মডেল উল্লেখ করব এন্ট ফ্রেমও

একক সংযোগ লোড করা

ধরা যাক, আমরা ডাটাবেস থেকে সব ব্যবহারকারী পেতে এবং প্রিলোড প্যাট ডাটা পেতে চাই। আমরা নিম্নলিখিত কোডটি লিখে এটি অর্জন করতে পারি:

users, err := client.User.
    Query().
    WithPets().
    All(ctx)
if err != nil {
    // ত্রুটি নিবারণ করুন
    return err
}
for _, u := range users {
    for _, p := range u.Edges.Pets {
        fmt.Printf("ব্যবহারকারী (%v) পালতু প্যাট (%v)\n", u.ID, p.ID)
    }
}

এই উদাহরণে, আমরা ব্যবহার করি WithPets মেথডটি যাতে ent-কে প্রিলোড করার জন্য আইন্টিটিগুলি টাঁকা বলা যায়। প্রিলোড প্যাট ডেটা Edges.Pets ফিল্ডে পুনরায় প্রবৃদ্ধি হয়, যার মাধ্যমে আমরা এই সংযুক্ত ডেটা অ্যাক্সেস করতে পারি।

একাধিক সংযোগ পূর্বাভুক্তকরণ

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

admins, err := client.User.
    Query().
    Where(user.Admin(true)).
    WithPets().
    WithGroups(func(q *ent.GroupQuery) {
        q.Limit(5)          // প্রথম 5 দলের সীমাবদ্ধ
        q.Order(ent.Asc(group.FieldName)) // দলের নাম অনুযায়ী আরোহো
        q.WithUsers()       // দলে ব্যবহারকারী প্রিলোড করুন
    }).
    All(ctx)
if err != nil {
    // ত্রুটি হ্যান্ডেল করুন
    return err
}
for _, admin := range admins {
    for _, p := range admin.Edges.Pets {
        fmt.Printf("অ্যাডমিন (%v) মালিক প্যাট (%v)\n", admin.ID, p.ID)
    }
    for _, g := range admin.Edges.Groups {
        fmt.Printf("অ্যাডমিন (%v) দলের সদস্য (%v)\n", admin.ID, g.ID)
        for _, u := range g.Edges.Users {
            fmt.Printf("দলে (%v) সদস্য (%v)\n", g.ID, u.ID)
        }
    }
}

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