【问题标题】:Linq-to-SQL query a listLinq-to-SQL 查询列表
【发布时间】:2015-05-22 09:28:09
【问题描述】:

这很可能很简单,只是我无法让它正常工作。

我有 2 个 c# 类:

市场

public string MarketId { get; set; }

public string Description { get; set; }

public virtual List<Dealer> Dealers { get; set; }

经销商

public string DealerId { get; set; }

public string City { get; set; }

public Market Market { get; set; }

我想要做的是获得一个或多个特定市场(marketid),并且只获得与(dealerid)匹配的经销商。可以是多个匹配项。

我试过这个:

dbMarkets = db.Markets.Where(x => x.MarketId.Equals(marketId) && x.Dealers.Select(c => c.DealerId).Contains(dealerId)).ToList();

然而,它返回属于某个市场的所有经销商,而不仅仅是匹配dealerid的经销商。

【问题讨论】:

  • 所以你想要作为经销商或市场的结果?或属于哪个市场和经销商的新实例?
  • 我想要一个市场列表,其中包含与每个市场内列表 中的dealerid 匹配的经销商。
  • 所以最终的结果将是 List,对吗?

标签: c# linq entity-framework ef-code-first code-first


【解决方案1】:

以下内容:

db.Markets
  .Where(o => o.MarketId.Equals(marketId))
  .Select(o => new Market{ 
    MarketId = o.MarketId,
    Description = o.Description,
    Dealers = db.Dealers.Where(k => k.DealerId == o.Dealers).ToList()
  })
  .ToList();

【讨论】:

  • 只是语法纳粹:这不是 Linq 而是 Lambda 表示法。
  • 然后它会抱怨“无法在 LINQ to Entities 查询中构造实体或复杂类型 'Market'。”
  • 您可以将 new Market{ 替换为 new {
【解决方案2】:

由于Market.Dealers属性只是一个导航,需要单独加载dealer。但是在这种情况下,每个Dealer也有Market作为导航属性,您可以查询到Dealer,包括Market,然后再按Market分组。像这样:

using (var db = new MyContext())
{
    // this is important since Market.Dealers is a navigation property,
    // without this it would load all dealers in the market.
    db.Configuration.LazyLoadingEnabled = false;

    // load all dealers and its market(using Include)
    // by specific marketId and dealerId.
    var dealers = db.Dealers
        .Include(o => o.Market)
        .Where(o => o.DealerId == dealerId && o.Market.Id == marketId)
        .ToList();

    // this will be executed in the client-side, 
    // so you don't need to worry about round-trip overhead.
    var markets = dealers
        .GroupBy(o => o.Market)
        .Select(o => o.Key)
        .ToList();
    Console.WriteLine("Check if all dealers also have market: " +
                  markets.SelectMany(o => o.Dealers).All(o => o.Market != null));
    Console.WriteLine("All dealers in the markets: " +
                  markets.SelectMany(o => o.Dealers).Count());
}

如果您不喜欢设置配置或编写额外代码(本例中为分组),您可以将市场信息和经销商投影为匿名对象。但是这种方法不能在每个 Dealers 上保留对 Market 属性的引用。

using (var db = new MyContext())
{
    var anonymousMarkets = db.Markets
        .Where(o => o.MarketId == marketId)
        .Select(o => new        // project as an anonymous object
        {
            o.MarketId,
            o.Description,
            Dealers = o.Dealers.Where(d => d.DealerId == dealerId)
        })
        .ToList();
    Console.WriteLine("Check if all dealers don't have market: " +
        anonymousMarkets.SelectMany(o => o.Dealers).All(o => o.Market == null));
    Console.WriteLine("All dealers in the markets: " + 
        anonymousMarkets.SelectMany(o => o.Dealers).Count());
}

最后,如果您想在每个 Dealers 上保留 Market 导航属性,您可以将 Market 和 Dealers 聚合在一起。

using (var db = new MyContext())
{
    var marketAggregates = db.Markets.Where(o => o.MarketId == marketId)
        .Select(o => new    // aggregate Market and Dealers as an anonymous object.
        {
            Market = o,
            Dealers = o.Dealers.Where(d => d.DealerId == dealerId)
        })
        .ToList();
    Console.WriteLine("Check if all dealers also have market: " +
          marketAggregates.SelectMany(o => o.Dealers).All(o => o.Market != null));
    Console.WriteLine("All dealers in the markets: " + 
          marketAggregates.SelectMany(o => o.Dealers).Count());
}

嗯,所有方法都有不同的优缺点,但我通常更喜欢最后一种。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多