Entity framework 实体框架核心-以通用方式检索除少数列以外的所有列

Entity framework 实体框架核心-以通用方式检索除少数列以外的所有列,entity-framework,ef-core-3.0,Entity Framework,Ef Core 3.0,我不知道有没有比这个更好的办法来解决我的问题 我有几个模型有很多列(比如说20列),很少有列是重的。 当然,我希望有一个方法以轻松的方式检索数据(它们的列表)——即排除这几个列。 到目前为止,唯一有效的方法是上面链接中提出的方法,即 原始型号: { public Rating() { } public int IdRating { get; private set; } public string IdUser { get; set; } public deci

我不知道有没有比这个更好的办法来解决我的问题

我有几个模型有很多列(比如说20列),很少有列是重的。 当然,我希望有一个方法以轻松的方式检索数据(它们的列表)——即排除这几个列。 到目前为止,唯一有效的方法是上面链接中提出的方法,即

原始型号:

{
    public Rating() { }
    public int IdRating { get; private set; }
    public string IdUser { get; set; }
    public decimal Value { get; private set; }
    public string Comment { get; private set; }
    public bool IsEnabled { get; set; }
    public int IdCorrespondent { get; private set; }}
然后是较轻的版本

public class RatingView
{
    public Rating() { }
    public int IdRating { get; private set; }
    public decimal Value { get; private set; }
}
并且数据检索是

public List<RatingView> ListRatings()
    {
        return _context.Ratings.Select(x => new RatingView
        {
            IdRating = x.IdRating ,
            Value = x.Value ,
        }).ToList();

    }
公共列表评级()
{
return\u context.Ratings.Select(x=>newratingview
{
IdRating=x.IdRating,
值=x.值,
}).ToList();
}
第一个问题是以这种方式设置的列太多,第二个问题是有几个类似的类,因此解决方案不是很好,并且在将来更改模型时很容易出错。 Automapper看起来是一个不错的方法,但生成的查询不是最优的——所有列都被检索

谢谢,
arbus

通过查看其他stackoverflow帖子,并在几个人的帮助下,我找到了5种解决方案,其中第一种对我来说是最好的——这要归功于Lucian Bargaoanu

1) 基于Automapper


事实上,甚至不需要创建字段数量有限的轻类——Automapper可以忽略重字段,生成的SQL查询将不会使用它们

var ratings = _db.Ratings.Where(...).ProjectTo<Rating>(new MapperConfiguration
    (cfg => { cfg.CreateMap<Rating, Rating>()
        .ForMember(d => d.Comment, m => m.Ignore())
        .ForMember(d1 => d1.IdUser, m1 => m1.Ignore()); })).ToList();
var ratings=\u db.ratings.Where(…).ProjectTo(新的MapperConfiguration)
(cfg=>{cfg.CreateMap()
.ForMember(d=>d.Comment,m=>m.Ignore())
.ForMember(d1=>d1.IdUser,m1=>m1.Ignore();})).ToList();
如果你想使用像RatingView这样的Light类,只需映射到它而不忽略任何东西

2) 数据库设计 在设计表格时,不要将这些沉重的列包含在表格中,如果需要,请在一个模型中创建一个视图。 不幸的是,如果您要继承该表,则它不是一个选项

3) EF核心表拆分(由Crypt32提出) 可以使用EF核心机制执行表拆分

这里也有很好的解释

我认为这是可能的,从EF核心版本3,这是在写作时不适用于我,因为我正在使用EF核心与Oracle。 数据库中不需要视图,也不需要映射和列出所有属性,但仍然需要创建这些灯光模型类

4) 初始解决方案也有效。
如前所述,缺点是需要创建许多轻量级类,编写具有许多属性的繁琐代码,然后在解决方案的发展过程中支持所有这些实体

Kevin Dockx建议了另外两种可能性,这两种可能性都非常好

5) 视图创建并将灯光模型类映射到它,如下所示:

Disadvantage需要支持轻类和视图,这与解决方案3的问题是一样的

6) SQL查询可以使用SQL查询机制,例如

var ratingLIghts= dbContext.Database.SqlQuery<Rating>("select ... from Ratings");
var ratingLIghts=dbContext.Database.SqlQuery(“从评级中选择…”);
7) Linq扩展 有人建议使用selectException之类的查询来扩展Linq,如下所示

有一段代码提示dthere无法最佳工作,因为它只是通过NULL填充要排除的列,但数据库上执行的查询正在读取所有列-这是不可接受的,但我相信可以以不同的方式实现它


因此,在我看来,最优雅的解决方案是第一个——感谢Lucian Bargaoanu

视情况而定。但是,当需要时,我会考虑将较少访问的列移动到单独的表,并使用<代码>连接< /代码>。比方说,如果额外(重)列的使用是轻查询的1/100倍——这可能是一个好方法。否则,您必须使用
select
编写手动投影。AM设计为在不同情况下具有不同的DTO-s。也就是说,感谢Crypt32,在数据库级别拆分表是最好的方法,但不幸的是,它仅在数据库设计阶段可用(在我的案例中是固有的)。第二个建议我不太明白。你是在建议var All=_context.Ratings.Where(…);var query=All.Select(x=>newratingview{IdRating=x.IdRating,Value=x.Value,}),所以最后我看不出它与初始解决方案有什么不同?大家好,arbusthanks Lucian,很有趣,但是在DbSet上使用.ProjectTo似乎可以得到最佳查询!!我会再做一些测试,但看起来真的很有希望!