ASP.NET MVC 4 - نماذج متداخلة - كيفية إعداد الجمعيات المناسبة؟

أنا قادم إلى asp.net MVC 4 من خلفية في القضبان ، وأنا أواجه بعض الصعوبة في معرفة كيفية التعامل مع النماذج المتداخلة.

أستخدم الكيان الإطاري 4.3 مع نهج CodeFirst.

التطبيق بسيط إلى حد ما ولديه نموذج Set - الذي يحتوي على العديد من الامتيازات . ولديها نموذج الامتياز - الذي ينتمي إلى مجموعات.

تم إنشاء فئات POCO مع خصائص التنقل المناسبة ، ثم قمت بحصر وحدات التحكم في طرق العرض ، ثم إنشاء قاعدة البيانات.

فيما يلي الطبقات:

على تعيين </قوي>

 namespace FranchiseManagerTest.Models
    {
        public class Set
        {        
            [Key]
            public int SetID { get; set; }
            public string SetName { get; set; }
            public string MainAddress { get; set; }
            public string TimeZone { get; set; }       
            public virtual ICollection Franchises { get; set; }
        }
    }

<�القوي> الامتياز </قوي>

namespace FranchiseManagerTest.Models
{
    public class Franchise
    {
        [Key]
        public int FranchiseID { get; set; }        
        public int SetID { get; set; }
        public string FranchiseName { get; set; }
        public string FranchiseNumber { get; set; }     

        public virtual Set Set { get; set; }

    }
}

ثم قمت بإنشاء بعض مجموعات الامتياز والاختبارات.

هنا هو الرأي الرئيسي:

enter image description here

يتطلب المشروع أن تكون جميع الامتيازات المتعلقة بمجموعة محددة مرئية في المجموعة المقابلة. أيضا ، أنا بحاجة إلى أن أكون قادرا على إضافة الامتياز إلى مجموعة بينما أنا في تفاصيل Set.

لقد أنشأت لقطة شاشة لتوضيح الشكل الذي تبدو عليه بعد النقر على "تفاصيل" في العرض الرئيسي:

enter image description here

يتم إنشاء زر امتياز جديد باستخدام ActionLink يشبه هذا:

@Html.ActionLink("New Franchise", "Create", "Franchise", null,  new { @class = "btn btn-large btn-primary" })

هذا يأخذني إلى صفحة إنشاء الامتياز التي تبدو كالتالي:

enter image description here

المشكلة ، كما ترون ، هي أن القائمة المنسدلة التي يجب أن تحتوي على مجموعة النماذج ذات الصلة لا يتم نشرها مسبقًا - بدلاً من ذلك ، يجب النقر على القائمة المنسدلة وإعادة تحديد المجموعة التي أستخدمها بالفعل.

القائمة المنسدلة هي يتم نشرها - ولكن من خلال جميع المجموعات الحالية - بدلاً من المجموعة التي أستخدمها داخل.

في ما يلي القائمة المنسدلة عندما أنقر عليها:

enter image description here

في داخل منح امتياز إنشاء عرض ، هذا ما تبدو عليه القائمة المنسدلة وملصقها:

       <div class="editor-label">
            @Html.LabelFor(model => model.SetID, "Set")
        </div>
        <div class="editor-field">
            @Html.DropDownList("SetID", String.Empty)
            @Html.ValidationMessageFor(model => model.SetID)
        </div>

إليك ما جربته:


حاولت تمرير قيمة SetID إلى العرض باستخدام ActionLink:

@Html.ActionLink("New Franchise", "Create", "Franchise", Model.SetID,  new { @class = "btn btn-large btn-primary" })

ثم حاولت تغيير السمة String.Empty من طريقة العرض "إنشاء" إلى هذا:

 <div class="editor-label">
        @Html.LabelFor(model => model.SetID, "Set")
    </div>
    <div class="editor-field">
        @Html.DropDownList("SetID", Model.SetID)
        @Html.ValidationMessageFor(model => model.SetID)
    </div>

على الرغم من ذلك ، لم ينجح ذلك وأحدث خطأ خطأ غير صالح .

إليك فكرة محتملة (أو مشكلة أخرى؟)

عندما أزور "إنشاء عرض الامتياز" من المجموعة المقترنة التي أجدها ، فإليك ما يبدو عليه عنوان URL:

enter image description here

I would assume that if the associations between على تعيين </قوي> and <�القوي> الامتياز </قوي> were correct, and when I went to add a Franchise within a Set, that the URL would look like this:

localhost:52987/Set/1/Franchise/Create

هل هذا افتراض خاطئ لجعل - هل هذا ممكن القيام به في .NET MVC؟

أي نصيحة هنا تحظى بتقدير كبير!


على التعديلات </قوي>


فيما يلي المسارات في ملف Global.asax الخاص بي إذا كان هذا مفيدًا:

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Set", action = "Index", id = UrlParameter.Optional }
            );
        }

كما هو مطلوب - في ما يلي طريقتان GET و POST Create من وحدة التحكم في الامتياز:

 //
   //GET: /Franchise/Create

    public ActionResult Create()
    {
        ViewBag.SetID = new SelectList(db.Sets, "SetID", "SetName");
        return View();
    }

    //
   //POST: /Franchise/Create

    [HttpPost]
    public ActionResult Create(Franchise franchise)
    {
        if (ModelState.IsValid)
        {
            db.Franchises.Add(franchise);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.SetID = new SelectList(db.Sets, "SetID", "SetName", franchise.SetID);
        return View(franchise);
    }

فقط اسمحوا لي أن أعرف ما إذا كان رمز أكثر سيكون مفيدا.

0
Hey Stripling - لقد أضفت رمز جهاز التحكم إلى قسم "التحرير" في ملفي OP. قد يكون شيء جيد للغاية مع وحدة تحكم - فقط لست متأكدا ما. لقد حاولت وضع معلمة لـ SetID في طريقة GET Create ، لكن لا حظ. مرة أخرى - أنا متأكد من أنني أفعل ذلك خطأ. أزلت المعلمة وهذا ما يبدو عليه الآن.
وأضاف المؤلف PhillipKregg, مصدر
حصلت عليه - يبدو أن العمل الآن. سأحاول إدخال الإدخال المخفي بعد ذلك. شكرا للمساعدة!
وأضاف المؤلف PhillipKregg, مصدر
ماذا تبدو طريقة FranchiseController.Create الخاصة بك؟
وأضاف المؤلف StriplingWarrior, مصدر
تحتاج إلى تغيير طريقة إنشاء الطريقة التي توحي بها justinb138. يجب أن تأخذ معلمة SetID بحيث يمكن استخدام القيمة التي تمررها من الرابط كقيمة افتراضية في القائمة المنسدلة. (قد ترغب أيضًا في جعلها تستخدم مدخلات مخفية لهذه القيمة بدلاً من القائمة المنسدلة ، ما لم تتوقع أن يقوم الأشخاص بتغيير الامتياز)
وأضاف المؤلف StriplingWarrior, مصدر

2 إجابة

من غير الواضح بالضبط كيفية إعداد إجراءاتك وطرقك ، ولكن قد ترغب في تجربة ذلك:

@Html.ActionLink("New Franchise", "Create", "Franchise", new{Model.SetID},  new { @class = "btn btn-large btn-primary" })

من خلال إنشاء كائن به خاصية SetID ، ستعرف MVC أن المعلمة يفترض أن تسمى "SetID".

PS--may I suggest renaming Set to (FranchiseSet, or FranchiseGroup, etc.), to avoid naming collisions? Set is one of the most ambiguous and common words in the English language.

0
وأضاف
شكرًا على التعليقات - لقد جربت استخدام الطراز {Model.SetId} الجديد ، إلا أن ذلك لم ينجح معي سواء للأسف. سأقوم بنشر المسارات في ملف Global.asax الخاص بي إذا كنت ترغب في ذلك - ولكنها المعايير التي يتم إنشاؤها بواسطة إطار العمل. لدي بالفعل تعيين باسم FranchiseSet في البداية - ولكن عندما تم إنشاء قاعدة البيانات ، فإنه ينشئ FranchiseSet_ID بدلاً من FranchiseSetID. لم يكن بإمكاني الحصول على الجمعيات للعمل حتى غيّرت الاسم. قد أحاول استخدام "Franchiseset" بدلاً من ذلك.
وأضاف المؤلف PhillipKregg, مصدر
PhillipKregg: فيما يتعلق باسم قاعدة البيانات: قد يعمل بشكل أفضل على تسميته FranchiseSetId بدلاً من FranchiseSetID . ربما يعتقد الإطار أنه يحتاج إلى إضافة تسطير للتمييز بين الأحرف الكبيرة أو شيء ما.
وأضاف المؤلف StriplingWarrior, مصدر

أنا مرتبك قليلاً بشأن ما تريد القيام به ، لكنني أقترح بعض التغييرات:

كنت أغير هذا:

<div class="editor-label">
    @Html.LabelFor(model => model.SetID, "Set")
</div>
<div class="editor-field">
    @Html.DropDownList("SetID", Model.SetID)
    @Html.ValidationMessageFor(model => model.SetID)
</div>

الى هذا:

<div class="editor-label">
    @Html.LabelFor(model => model.SetID, "Set")
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.SetID, (SelectList)ViewBag.FranchiseSets)
    @Html.ValidationMessageFor(model => model.SetID)
</div>

في حالة تمرير قيمة SetID إلى إنشاء ActionMethod وتعيينها ، فيجب تمريرها إلى العرض. يبدو أنك لا تقوم بملء DropDownList ، لذلك ليس هناك خيار في قائمة التحديد التي سيتم اختيارها.

public ActionResult Create(int SetID)
{
    ViewBag.FranchiseSets = new SelectList(...);
    var franchise = new Franchise { SetID = SetID };
    return View(franchise);
}
0
وأضاف
شكرا للمساعدة. انها في الاساس بسيطة التطبيق CRUD. يجب تنفيذ إجراءات CRUD على العناصر الفرعية أثناء وجود العنصر الرئيسي. يتم بالفعل اختيار قائمة التحديد الموجودة في طريقة عرض إنشاء الامتياز بواسطة جميع مجموعات الامتياز الموجودة. تكمن المشكلة في أنني أقوم بإنشاء الامتياز الجديد داخل مجموعة - بحيث يجب أن يتم إظهار المجموعة بالفعل في القائمة المنسدلة ، دون أن يضطر المستخدم للنقر على القائمة المنسدلة وإعادة تحديد المجموعة التي كانت موجودة بالفعل. هل هذا منطقي؟
وأضاف المؤلف PhillipKregg, مصدر
عظيم - حاول هذا ويبدو أنه يعمل الآن. شكرا لمساعدتك!
وأضاف المؤلف PhillipKregg, مصدر
+1 ، إجابة رائعة!
وأضاف المؤلف StriplingWarrior, مصدر