العثور على النمط الصحيح للكائنات تحميل مع الرسوم البيانية المختلفة

StackOverflow https://stackoverflow.com/questions/1027728

سؤال

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

وعلى سبيل المثال وفيما يلي عينة من كائنات المجال الخاص بي:

public class Puzzle
{
    public Id{ get; private set; }
    public string TopicUrl { get; set; }
    public string EndTopic { get; set; }
    public IEnumerable<Solution> Solutions { get; set; }
    public IEnumerable<Vote> Votes { get; set; }
    public int SolutionCount { get; set; }
    public User User { get; set; }
}
public class Solution
{
    public int Id { get; private set; }
    public IEnumerable<Step> Steps { get; set; }
    public int UserId { get; set; }
}  
public class Step
{
    public Id { get; set; }
    public string Url { get; set; }
}
public class Vote
{
    public id Id { get; set; }
    public int UserId { get; set; }
    public int VoteType { get; set; }
}

ما أحاول فهمه هو كيفية تحميل هذه المعلومات بشكل مختلف اعتمادا على كيفية أنا استخدامه.

وعلى سبيل المثال، على الصفحة الأولى لدي قائمة من كل الألغاز. في هذه المرحلة لا يهمني حقا عن حلول للغز أو الخطوات في تلك الحلول (التي يمكن الحصول على زيادات كبيرة جدا). كل ما أريده هي الألغاز. وأود أن تحميلها من وحدة تحكم بلدي مثل هذا:

public ActionResult Index(/*  parameters   */)
{
    ...
    var puzzles = _puzzleService.GetPuzzles();
    return View(puzzles);
}

وفي وقت لاحق للرأي لغز يهمني الآن عن حلول فقط للمستخدم الحالي. أنا لا أريد لتحميل الرسم البياني بأكمله مع كافة الحلول وكافة الخطوات.

public ActionResult Display(int puzzleId)
{
   var puzzle = _accountService.GetPuzzleById(puzzleId);
   //I want to be able to access my solutions, steps, and votes. just for the current user.
}

وداخل بلدي IPuzzleService، أساليبي تبدو مثل هذا:

public IEnumerable<Puzzle> GetPuzzles()
{
    using(_repository.OpenSession())
    {
        _repository.All<Puzzle>().ToList();
    }
}
public Puzzle GetPuzzleById(int puzzleId)
{
    using(_repository.OpenSession())
    {
        _repository.All<Puzzle>().Where(x => x.Id == puzzleId).SingleOrDefault();
    }
}

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

وأنا في محاولة لمعرفة ما النمط المناسب لاستخدام هنا. هل يجب الزائدة مختلفة على خدمتي مثل GetPuzzleWithSolutionsAndVotes أو أكثر نظرا محددة مثل GetPuzzlesForDisplayView وGetPuzzlesForListView؟

وأنا جعل الشعور؟ أنا بعيدا القاعدة؟ الرجاء المساعدة.

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

المحلول

وكان لي قضية مماثلة حيث لم أتمكن من استخدام تحميل كسول.

إذا ما عليك سوى واحد أو اثنين من الحالات، فإن أسهل شيء كما اشرتم، وخلق طرق منفصلة GetPuzleWithXYZ ().

ويمكنك أيضا إنشاء كائن الاستعلام صغير مع واجهة بطلاقة.

وشيء من هذا القبيل ...

public interface IPuzzleQuery
{
    IPuzzleLoadWith IdEquals(int id);
}

public interface IPuzzleLoadWith
{
    ISolutionLoadWith WithSolutions();

    IPuzzleLoadWith WithVotes();
}

public interface ISolutionLoadWith
{
    IPuzzleLoadWith AndSteps();
}

public class PuzzleQueryExpressionBuilder : IPuzzleQuery, IPuzzleLoadWith, ISolutionLoadWith
{
    public int Id { get; private set; }
    public bool LoadSolutions { get; private set; }
    public bool LoadVotes { get; private set; }
    public bool LoadSteps { get; private set; }

    public IPuzzleLoadWith IdEquals(int id)
    { 
        Id = id;
        return this;    
    }

    public ISolutionLoadWith WithSolutions()
    {
        LoadSolutions = true;
        return this;
    }

    public IPuzzleLoadWith WithVotes()
    {
        LoadVotes = true;
        return this;
    }

    public IPuzzleLoadWith AndSteps()
    {
        LoadSteps = true;
        return this;
    }
}

وبعد ذلك مستودع الخاص بك الحصول الأسلوب () يمكن إنشاء مثيل منشئ التعبير وتمريرها إلى المتصل

public Puzzle Get(Action<IPuzzleQuery> expression)
{
    var criteria = new PuzzleQueryExpressionBuilder();

    expression(criteria);

    var query = _repository.All<Puzzle>().Where(x => x.Id == criteria.Id)

    if(criteria.LoadSolutions) ....

    if(criteria.LoadSteps) ....

    if(criteria.LoadVotes) ....

    ...
    ... 

    return query.FirstOrDefault();
}
أن

ونموذجية المكالمات ستبدو ...

Puzzle myPuzzle = Repository.Get(where => where.IdEquals(101).WithSolutions());

Puzzle myPuzzle = Repository.Get(where => where.IdEquals(101).WithSolutions().AndSteps());

Puzzle myPuzzle = Repository.Get(where => where.IdEquals(101).WithVotes().WithSolutions());

وانها تحتاج الى القليل من العمل، لكن يمكنك أن ترى الفكرة الأساسية.

نصائح أخرى

وأنا لا أعتقد يجب أن يكون خدمتكم في أي معرفة طرق العرض. قد تتغير الاحتياجات الخاصة بك حتى لا ربط أسمائهم لعرض الأسماء.

عند استدعاء GetPuzzles () يجب عليك فقط تحميل لغز الجذر، وGetPuzzleById (الباحث معرف) يمكن تحميل حريصة الجمعيات.

وعلى سبيل المثال في API معايير: .SetFetchMode("Solutions", NHibernate.FetchMode.Join)

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

وهكذا يجب أن يكون تحكم تحميل أجزاء معينة من البيانات التي تحتاج إليها، لتحميل فقط للمستخدم، وأود أن تغيير واجهة مثل ما يلي: GetPuzzle(puzzleId,user)

في هذه الطريقة يمكنك تحميل فقط حريصة البيانات لمستخدم واحد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top