简体   繁体   English

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

[英]Entity framework with 2 joins on same table for column 1 or column 2

I am trying to construct an EF query to either return column 1 or column 2. 我正在尝试构造一个EF查询以返回第1列或第2列。

Column 1 is pulled from a different table based on the relationships/join of the query. 列1是根据查询的关系/联接从其他表中提取的。

Column 2 is pulled from the joined table. 从连接表中拉出第2列。

This is for a survey/answer model. 这是用于调查/答案模型的。 Some answers are hardcoded (eg user picks from a list) and some are free text. 有些答案是硬编码的(例如,用户从列表中选择),而有些则是自由文本。

Free text get saved in a table, and the user picked value is stored in a different table. 自由文本将保存在表中,而用户选择的值将存储在其他表中。

End goal is to have a POCO class with the question and answer: 最终目标是开设一个带有答疑的POCO课:

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

My query looks like: 我的查询看起来像:

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();

And here is some of the data which shows why the join on optionalanswer loses the last row 以下是一些数据,这些数据显示了为什么对可选答案的联接会丢失最后一行

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

Apparently your query generates inner join in sql and thus it eliminates Answer with empty PossibleAnswerID . 显然,您的查询在sql中生成inner join联接,因此它消除了带有空的PossibleAnswerID Answer So you just need to change it to left join . 因此,您只需要将其更改为left join It can be done like this 可以这样做

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();

If you use fluent syntax, .Select can accept an Expression<Func<TEntity, TResult>> argument. 如果使用流利的语法,.Select可以接受Expression<Func<TEntity, TResult>>参数。

Simplified: 简化:

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

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

SomeClass could maybe simply be this depending on what exactly you need: 根据您的实际需求, SomeClass可能就是这样:

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

SomeMethod is where you would define which value needs to be returned from your query: SomeMethod是您在其中定义需要从查询中返回哪个值的地方:

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

In the Expression you can also make use of navigation properties to access columns in a different table. Expression您还可以使用导航属性来访问其他表中的列。

I am making the assumption here that both your columns have the same datatype. 我在这里假设您的两个列都具有相同的数据类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM