首页 > 解决方案 > .NET Core 中是否有类似于 Ruby on Rails 中的 ActiveRecord 的东西?

问题描述

我正在从 Rails 切换到 .NET Core,但我真正想念的是 ActiveRecord ORM。在模型中,您只需定义关系:

#Town Model
class Town < ApplicationRecord
  belongs_to :country
end

#Country Model
class Country < ApplicationRecord
  has_many :towns
end

然后您可以简单地获取特定国家/地区所有城镇的列表:

@country = Country.find(params[:id])
@towns = @country.towns

这很清楚,尤其是在您将多个模型链接到 id 的情况下。在 .Net Core 中,我通常会遇到这样的情况:

Task<List<Town>> towns = await _context.Towns.Where(x => x.CountryId == countryId).ToListAsync();

这仍然是可以接受的,但这只是因为只有模型 - 模型关系。

假设我们想要在 Rails 中获得选定城镇的大陆:

@town = Town.find(params[:id])
@continent = @town.country.continent

在 .NET Core 中,现在我必须使用 Joins,最终结果会非常复杂,在这里很容易出错(甚至不是复杂的情况)。图像具有非常复杂的 SQL 查询,LINQ 对你没有多大帮助,你非常接近于编写纯 SQL。

这就是为什么我要问,.NET Core 中是否有类似于 Rails 中非常方便的 ActiveRecord ORM 的东西。

感谢您的回复和时间。

标签: c#ruby-on-railsrubyasp.net-coreactiverecord

解决方案


EF 支持开箱即用的导航属性,因此在简单的情况下您不需要连接。如果你愿意,你也可以使用延迟加载。例如,在此处此处此处查看更多信息。

在您的情况下,如果您正确设置实体之间的关系,您可以翻译

@country = Country.find(params[:id])
@towns = @country.towns

进入:

var country = await _context.Country.Include(c => c.Towns).FindAsync(countryId); 
// or await _context.Country.Include(c => c.Towns).FirstAsync(c => c.Id == countryId) 
var towns = country.Towns;

或者启用延迟加载:

var country = await _context.Country.FindAsync(countryId); 
var towns = country.Towns;

第二个片段:

@town = Town.find(params[:id])
@continent = @town.country.continent

可以翻译成:

var town = await _context.Town
     .Include(t => t.Country)
     .ThenInclude(c => c.Continent)
     .FindAsync(TownId); 
var country = town.Country.Continent;

推荐阅读