Linq to SQL ordered child collection
Is there a way to define a default order column from a child collection? In my case, I have a Form entity that has a collection of FormItem entities called FormItems. FormItem has a property called DisplayOrder (int). I want to make s开发者_运维百科ure that any Form entities I return from a method have that collection properly ordered. Is there a way to do this before returning the result?
For example, I tried this but the list is not actually sorted:
var form = context.Forms.FirstOrDefault(x => x.IsDeleted == false && x.FormName == formName);
if (form != null)
{
form.FormItems.OrderBy(x => x.DisplayOrder);
// I can't even figure out a way to cast this next line so that it will compile
// form.FormItems = form.FormItems.OrderBy(x => x.DisplayOrder);
}
return form;
Is there a way to do this without using DataLoadOptions?
Try this:
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Form>(f => f.FormItems);
loadOptions.AssociateWith<Form>(f =>
f.FormItems
.OrderBy(fi => fi.DisplayOrder);
);
context.LoadOptions = context;
var form = context.Forms
.FirstOrDefault(x =>
!x.IsDeleted &&
x.FormName == formName
);
meaning, ordering of child items made by DataLoadOptions.AssociateWith
method.
You could add an additional property to your Form
entity trough a partial class that would return the ordered FormItems
.
partial class Form
{
public IQueryable<FormItem> OrderedFormItems
{
get { return FormItems.OrderBy(x => x.DisplayOrder); }
}
}
First, Make FormItems private and change name to PrivateFormNames in designer.
Than you should be able to declare:
partial class Form
{
public IQueryable<FormItem> FormItems
{
get { return PrivateFormItems.OrderBy(x => x.DisplayOrder); }
}
}
I will think how you can make it virtual... Something like this: You can create Derived class for Form in linq digram, and set inheritance in that way, that it always create derived Form class (You can specify inheritence default).
Than you can mark FormItems as virtual and override it in derived class:
partial class FormDerived
{
public override IQueryable<FormItem> FormItems
{
get { return base.FormItems.OrderBy(x => x.DisplayOrder); }
}
}
and ALL linq and application will start to use ordered list. Only option to get it unordered will be to use context.FormItems.
what about:
var form2 = form.FormItems.OrderBy(x => x.DisplayOrder);
return form2;
One option would be
public static class FormExtensions
{
public static IQueryable<FormItem> GetOrderedItems(this Form form)
{
// without lazy loading, but you have to get current context somehow
return CurrentContext.FormItems.Where(x => x.FormId == form.Id).OrderBy(x => x.DisplayOrder);
// with lazy loading
return form.FormItems.OrderBy(x => x.DisplayOrder);
}
}
or create reprository layer for stuff like that
精彩评论