我在SQL中尝试做的事情如下:
List<Criteria> criterias = new ArrayList<Criteria>();
...
while (matcher.find())
{
String key = matcher.group(1);
String operator = matcher.group(2);
String value = matcher.group(3);
// get from map appropriate implementation
criterias.add(expressions.get(operator).toCriteria(key, value));
}
在Lead模型中:
SELECT
....
ct.FirstName + ' ' + ct.LastName
....
FROM
Leads l
LEFT JOIN LeadContacts lc ON lc.LeadID = l.LeadID
LEFT JOIN Contacts ct on ct.ContactID = lc.ContactID
在LeadContact模型中:
public class Lead
{
....
public virtual ICollection<LeadContact> LeadContacts { get; set; }
....
}
现在,我正在尝试从以下实例构建对象:
public class LeadContact
{
....
[ForeignKey(nameof(LeadID))]
public virtual Lead Lead { get; set; }
[ForeignKey(nameof(ContactID))]
public virtual Contact Contact { get; set; }
....
}
对于我的生活,我无法弄清楚如何导航到联系人表格。
leads = IQueryable<Lead>...
QuoteSearchItem.LeadSales是一个字符串。它必须是:
var results = leads.Select(l => new QuoteSearchItem
{
....
SomeProperty = l.SomeProperty,
LeadSales = l.LeadContacts. ?????
SomeOtherProperty = l.SomeOtherProperty
....
});
由于关系类型,l.LeadContacts.Contacts不是一个选项。
我需要做什么才能做到这一点?
答案 0 :(得分:1)
您可以执行以下操作:
l.LeadContacts.SelectMany(x => x.Contacts)
但是,您的Contact
属性不是LeadContact
类中的列表。因此,要么将其设为列表,要么可以像以下一样访问它:
l.LeadContacts.Select(x => x.Contact)
答案 1 :(得分:1)
如果你使用理解语法(当有多个froms时使用SelectMany),你可以轻松地做到这一点:
var query = from l in Leads
from lc in l.LeadContacts.DefaultIfEmpty()
from ct in lc.Contacts.DefaultIfEmpty()
select new
{
//....
ContactName = ct.FirstName + ' ' + ct.LastName
//....
};
如果您愿意,在LinqPad中运行它,您可以获得lambda版本+,如果这是SQL本身的Linq To SQL。
编辑:您的课程暗示每个LeadContact都有一个联系人,那么您可以缩短它:var query = from l in Leads
from lc in l.LeadContacts.DefaultIfEmpty()
select new
{
//....
ContactName = lc.Contact.FirstName + ' ' + lc.Contact.LastName
//....
};
它几乎映射到使用Northwind示例数据库的此示例:
var data = from c in Customers
from o in c.Orders.DefaultIfEmpty()
select new {
CustomerId = c.CustomerID,
OrderId = (int?)o.OrderID,
Employee = o.Employee.FirstName + ' ' + o.Employee.LastName
};
产生这个SQL:
-- Region Parameters
DECLARE @p0 NChar(1) = ' '
-- EndRegion
SELECT [t0].[CustomerID] AS [CustomerId], [t1].[OrderID] AS [OrderId], ([t2].[FirstName] + @p0) + [t2].[LastName] AS [Employee]
FROM [Customers] AS [t0]
LEFT OUTER JOIN [Orders] AS [t1] ON [t1].[CustomerID] = [t0].[CustomerID]
LEFT OUTER JOIN [Employees] AS [t2] ON [t2].[EmployeeID] = [t1].[EmployeeID]
编辑:我在说什么,而不是:
var results = leads.Select(l => new QuoteSearchItem
{
....
LeadSales = l.LeadContacts. ?????
....
});
这样做:
var results = from l in leads
from lc in l.LeadContacts.DefaultIfEmpty()
select new QuoteSearchItem
{
....
LeadSales = lc.Contact.FirstName + " " + lc.Contact.LastName
....
};
在(方法)lambda形式或理解语法中,最终结果相同。当需要selectMany时,我发现理解语法更容易。正如我所说,如果你正在为方法语法而死,那么试试在LinqPad中运行它,它会给你lambda对应的东西,比如:
var result = leads
.SelectMany (
l => l.LeadContacts.DefaultIfEmpty (),
(l, lc) =>
new QuoteSearchItem
{
//...
LeadSales = lc.Contact.FirstName + " " + lc.Contact.LastName
}
);
答案 2 :(得分:1)
首先,您需要在 LeadContact 表中使用外键。我假设你的Lead表有一个LeadId字段:
//Foreign key for Standard
public int LeadId { get; set; }
[ForeignKey("LeadId")]
public Lead Lead { get; set; }
表示潜在客户和潜在客户联系人之间的关系,它会将记录限制为您想要的记录。 LeadContact是一个交叉引用,因此我确信它已经有一个“LeadId”字段(或其他名称),它映射到Lead表中的Lead Id字段,因此请指明上述关系。
假设LeadSales的类型为IEnumerable<string>
,您可以执行以下操作:
var results = leads.Select(l => new QuoteSearchItem
{
....
LeadSales = l.LeadContacts.Select(lc => lc.Contact.FirstName + " " + lc.Contact.LastName);
....
});
答案 3 :(得分:0)
您使用的是上下文吗?
var result = await context.SearchLead.AsNoTracking()
.Where(l => l.LeadContacts.Any(lc => lc.Contact == QuoteSearchItem))
.ToListAsync();