在第1列或第2列的同一表上具有2个连接的实体框架

时间:2019-02-07 23:39:54

标签: c# sql entity-framework

我正在尝试构造一个EF查询以返回第1列或第2列。

根据查询的关系/联接从不同的表中提取列1。

第2列是从联接表中拉出的。

这是针对调查/答案模型的。有些答案是硬编码的(例如,用户从列表中选择),有些则是自由文本。

自由文本保存在表中,而用户选择的值存储在另一个表中。

最终目标是开设一个带有问与答的POCO课程:

public class SurveyResponse
{
    public string Question { get; set; }
    public string Answer { get; set; }
}

我的查询如下:

var surveyResponses = (from ias in dataContext.AnswerSet
                       join answer in dataContext.Answer on ias.AnswerSetID equals answer.AnswerSetID
                       join oa in dataContext.OptionalAnswer on answer.PossibleAnswerID equals oa.OptionalAnswerID // this line loses valuetext answer
                       where ias.LeadID.Equals(dbLead.leadID)
                       select new SurveyResponse() { Question = "question(todo)", Answer = (answer.ValueText != "" ? answer.ValueText : oa.Title)}).ToList();

以下是一些数据,这些数据显示了为什么可选答案上的联接丢失最后一行

PossibleAnswerID    ValueText
979D3ADF-4F9C-4F4D-AC9C-034CE960003A    
EF488701-683D-4855-A9A7-7F9D78468E63    
D442F616-6D4B-4176-9F08-133E2C655BE4    
5FD57A95-B385-4CAE-ADAB-1711CEA00A08    
NULL    Questions about sales

2 个答案:

答案 0 :(得分:1)

显然,您的查询在sql中生成了inner join,因此它消除了Answer和空的PossibleAnswerID。因此,您只需要将其更改为left join。可以这样

var surveyResponses = 
    (from ias in dataContext.AnswerSet
     join answer in dataContext.Answer on ias.AnswerSetID equals answer.AnswerSetID
     join oa in dataContext.OptionalAnswer on answer.PossibleAnswerID equals oa.OptionalAnswerID into optans // this line loses valuetext answer
     from oa in optans.DefaultIfEmpty()
     where ias.LeadID.Equals(dbLead.leadID)
     select new SurveyResponse() { Question = "question(todo)", Answer = (answer.ValueText != "" ? answer.ValueText : oa.Title)}).ToList();

答案 1 :(得分:0)

如果使用流利的语法,.Select可以接受Expression<Func<TEntity, TResult>>参数。

简体:

Expression<Func<AnswerSetType, SomeClass>> func = SomeMethod();

dataContext.AnswerSet
    .Select(func)
    .ToList();

SomeClass可能仅仅是取决于您的实际需求:

public class SomeClass 
{
    public string ValueFromColumn1OrColumn2 { get; set; }
}

SomeMethod是您定义需要从查询中返回哪个值的地方:

public Expression<Func<AnswerSetType, SomeClass>> SomeMethod()
{
    if (condition)
    {
        return (answerSetType => new SomeClass { ValueFromColumn1OrColumn2 = answerSetType.Column1 });
    }
    else
    {
        return (answerSetType => new SomeClass { ValueFromColumn1OrColumn2 = answerSetType.Column2 });
    }
}

Expression中,您还可以使用导航属性来访问其他表中的列。

我在这里假设两个列都具有相同的数据类型。