C# 在从数据库请求的类中对列表进行排序
我有一个包含参数列表的类。例如:C# 在从数据库请求的类中对列表进行排序,c#,entity-framework,C#,Entity Framework,我有一个包含参数列表的类。例如: public class Container { public List<Parameter> Parameters { get; set; } } public class Parameter { puplic string Name {get; set;} } 通过实体框架从数据库中获取的С类容器。许多类包含容器。我需要确保包含Сcontainer的所有类以及从包含已排序参数列表的数据库中检索的所有类。也就是说,容器必须对参数进行
public class Container
{
public List<Parameter> Parameters { get; set; }
}
public class Parameter
{
puplic string Name {get; set;}
}
通过实体框架从数据库中获取的С类容器。许多类包含容器。我需要确保包含Сcontainer的所有类以及从包含已排序参数列表的数据库中检索的所有类。也就是说,容器必须对参数进行排序,或请求步骤,或随后立即进行排序。
如何做到这一点?
可能会写入配置
internal class ContainerConfiguration : EntityTypeConfiguration<Container>
{
public ContainerConfiguration()
{
ToTable("Container");
HasKey(p => p.Id);
... ???
}
}
或数据集中的wright
protected override IQueryable<Container> DataSet(DbContext db)
{
return db.Set<ProcessMeasurer>()
.Include(it => it.Parameters.Select(p => p.Parameter));
}
需要使用实体类。 如果我们想对组成集合的所有元素中的集合进行排序,我们必须更改相应的属性。 明显的变量-创建属性设置器
private List<Parameter> _parameters;
public List<Parameter> Parameters
{
get { return _parameters; }
set { _parameters = value.OrderBy(...).ToList();
}
它起作用了。但问题是,当EntityFramework插入每个值时,将向getter发出请求,从而进行排序。这会影响性能
目前我知道的最好的变体是使用函数Prepare从接口继承所有实体
public interface IEntity
{
void Prepare();
}
并在每个类模型中实现它。包含其他模型的模型导致为每个所需属性准备方法
public class SomeModel : IEntity
{
public CustomType SomeProperty { get; set; }
public OneMoreCustomType AnotherProrerty { get; set; }
public void Prepare()
{
SomeProperty.Prepare();
AnotherProperty.Prepare();
}
}
对于相应的类别,它将采取适当的行动。包括分类。
在这种情况下,在使用前准备С容器的所有方法。
例如,在业务逻辑MVPVM中。解决问题的另一个选项: 创建属性并指定默认情况下用于排序的字段:
public class DefaultOrderFieldAttribute : Attribute
{
public DefaultOrderFieldAttribute()
{
}
public string FieldName { get; set; }
}
[DefaultOrderField(FieldName = "ParameterName")]
public partial class Parameter
{
}
编写一个访问者,在检测到我们的属性时,它会修改select:
public class DefaultOrderVisitor : DefaultExpressionVisitor
{
public override DbExpression Visit(DbScanExpression expression)
{
const string NAMESPACE = "OrderTest";
var type =
Assembly.GetExecutingAssembly().GetType(string.Format("{0}.{1}", NAMESPACE, expression.Target.Name));
var attribute =
type.GetCustomAttributes(typeof (DefaultOrderFieldAttribute)).SingleOrDefault() as
DefaultOrderFieldAttribute;
if (attribute != null)
return expression.OrderBy(ex => ex.Property(attribute.FieldName));
return expression;
}
}
请输入我们的访客拦截器:
public class DefaultOrderInterceptor : IDbCommandTreeInterceptor
{
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
{
var queryCommand = interceptionContext.Result as DbQueryCommandTree;
if (queryCommand != null)
{
var newQuery = queryCommand.Query.Accept(new DefaultOrderVisitor());
interceptionContext.Result = new DbQueryCommandTree(queryCommand.MetadataWorkspace,
queryCommand.DataSpace, newQuery);
}
}
}
}
并将其注册到配置中。该类必须与模型位于同一程序集中:
public class EntityFrameworkConfiguration : DbConfiguration
{
public EntityFrameworkConfiguration()
{
AddInterceptor(new DefaultOrderInterceptor());
}
}
那是什么?这不是答案-1.描述我对这个问题的想法、实验和建议。但是如果有人知道使用标准EntityFramework工具解决这个问题的方法,或者只是最好的选择,请分享。下面的答案也是一个很好的答案。当他投-1时,我没有完成
public class EntityFrameworkConfiguration : DbConfiguration
{
public EntityFrameworkConfiguration()
{
AddInterceptor(new DefaultOrderInterceptor());
}
}