【问题标题】:how to use linq to return a value from 4 tables如何使用 linq 从 4 个表中返回一个值
【发布时间】:2016-12-07 10:24:14
【问题描述】:

我对 Linq 相当陌生,它似乎很容易使用,但在尝试从由其他 3 个表链接/约束的表中提取值时遇到问题。

我的 SQL DB 中有这个:

我正在使用 Asp.Net 4 和 Entity Framework 6。

我将“数据库名称”作为参数。

我最终想要获得分配给此名称的 SubscriptionRef。

我可以逐步执行此操作(即使用多个 linq),但我认为仅使用 1 个 linq 语句会看起来很“干净”。

我已经做到了:

var names = o.RegisteredNames.Where(d => d.DatabaseName == DBName).Where(d => d.ClientNames.Where(f => f.ClientId == f.Client.ClientId).FirstOrDefault();

但我得到了错误:

Cannot implicitly convert type 'Services.ClientName' to 'bool'

【问题讨论】:

  • .Where() 返回一个 IEnumerable,其中包含通过该子句的元素。我想你可能想看看.Include()
  • @Bas 谢谢 - 我现在就这样做
  • 我会说一步一步地做这个比一个巨大的声明更干净。首先它更容易阅读,其次它更容易调试。
  • @ThomasSchneiter 感谢值得考虑的一点。我现在处于需要知道如何做到这一点的位置,但最终可能会按照你的建议做:)
  • 如果我们有您的客户和服务对象模型,这会有所帮助。

标签: c# asp.net entity-framework linq


【解决方案1】:

这里有问题:

d => d.ClientNames.Where(f => f.ClientId == f.Client.ClientId)

f => ... 返回单个 ClientNamenull,这会导致您的错误,因为应该有一个布尔值。 如果你想要这个第一个值或 null,你应该替换

.Where(d => d.ClientNames ...
//with
.Select(d => d.ClientNames ...

【讨论】:

  • 谢谢,我会测试一下。我需要修复一些错误才能发布,所以请多多包涵:)
  • 嘿,没关系 - 如果这不是你需要的,请告诉我,这样我就可以删除答案,因为它不需要那么
  • 嗨,看着这个我还是看不到如何获取订阅参考?
  • 如果subscriptionRef 在您的客户名称中,您应该可以通过.SubcriptionRef 后面的.FirstOrDefault() 获得它
  • SubscriptionRef 只出现在 Client 和 Subscription 表中
【解决方案2】:

试试这个:

o.RegisteredNames.First(d => d.DatabaseName == DBName).ClientNames.Select(x=>x.Client.Subscription.SubscriptionRef)

它应该给你列出去 SubscriptionRef。

【讨论】:

  • 感谢我们会在发布/测试后尽快回复
【解决方案3】:

您可以尝试使用LINQ 查询,例如...

var names = o.RegisteredNames.Where(d => d.DatabaseName == DBName ).FirstOrDefault();

【讨论】:

  • 谢谢,我需要修复一些错误,然后才能发布和测试 :)
  • 没关系。但你也可以这样做.. :)
  • 没有编译?它告诉我 RegisteredName 不包含 ClientId 的定义?
【解决方案4】:

你可能想试试 sql 风格:

var client = from c in db.Clients 
  join cn in db.ClientNames on c.ClientId equals cn.ClientId 
  join rn in db.RegisteredNames on cn.RegisteredNamesId equals rn.RegisteredNameId 
  where rn.DatabaseName == "YourDBName"
  select c;

但这也取决于您的对象是如何构建的。

【讨论】:

  • 谢谢我,我可以做到这一点,但我想看看我是否可以避免使用连接,而使用 linq 的智能感知似乎表明
【解决方案5】:

尝试使用连接:

var names  = (
           from names in o.RegisteredNames.Where(d => d.DatabaseName == DBName)
           join cnames in o.ClientNames on names.RegisteredNamesId equals cnames.RegisteredNamesId
           select cnames.ClientId
         ).FirstOrDefault();

添加任意数量的连接。

【讨论】:

  • 谢谢我,我可以做到这一点,但我想看看我是否可以避免使用连接,而使用 linq 的智能感知似乎表明
【解决方案6】:

试试这个
它适用于列表,

var option1= o.RegisteredNames
                .Where(g => g.DbName == "YourDbName")
                .Where(h => h.ClientNames.Any(f => f == 5))
                .FirstOrDefault();

var option2= o.RegisteredNames
               .FirstOrDefault(h => h.DbName == "Name" && h.ClientNames.Any(j => j == 1));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    相关资源
    最近更新 更多