这可能是一个基本的LINQ问题。我需要选择一个对象,如果为null则选择另一个对象。我正在以下列方式使用linq对象,我知道可以更快,更好,更清洁......
public Attrib DetermineAttribution(Data data)
{
var one = from c in data.actions
where c.actionType == Action.ActionTypeOne
select new Attrib
{
id = c.id,
name = c.name
};
if( one.Count() > 0)
return one.First();
var two = from c in data.actions
where c.actionType == Action.ActionTypeTwo
select new Attrib
{
id = c.id,
name = c.name
};
if (two.Count() > 0 )
return two.First();
}
两个linq操作仅在where子句上有所不同,我知道有一种方法可以将它们组合在一起。任何想法都将不胜感激。
答案 0 :(得分:6)
我认为这个解决方案简单而有效:
public Attrib DetermineAttribution(Data data)
{
var c = data.actions.FirstOrDefault(c => c.actionType == Action.ActionTypeOne) ??
data.actions.FirstOrDefault(c => c.actionType == Action.ActionTypeTwo);
return c != null ? new Attrib { id = c.id, name = c.name } : null;
}
答案 1 :(得分:1)
这不使用查询语法,但它保留了类型ActionTypeOne
的元素在ActionTypeTwo
元素之前返回的逻辑。由于延迟评估,除非没有ActionTypeOne
类型的元素,否则不会执行第二个查询。
public Attrib DetermineAttribution(Data data)
{
return data.actions.Where( c => c.actionType == Action.ActionTypeOne)
.Concat( data.actions.Where( c.actionType == Action.ActionTypeTwo ) )
.Select( c => new Attrib
{
id = c.id,
name = c.name
})
.FirstOrDefault();
}
答案 2 :(得分:0)
var one = (from c in data.actions
where (c.actionType == Action.ActionTypeOne) || (c.actionType == Action.ActionTypeTwo)
select new Attrib
{
id = c.id,
name = c.name
}).FirstOrDefault();
这并不能保证在ActionTypeTwo之前找到ActionTypeOne。它找到第一个记录,即ActionTypeOne 或 ActionTypeTwo。
答案 3 :(得分:0)
我建议:
public Attrib DetermineAttribution(Data data)
{
var types = Enum.GetValues(typeof (Action)).Cast<Action>();
var merged = from c in data.actions
from t in types
where c.actionType == t
select new Attrib {id = c.id, name = c.name};
return merged.FirstOrDefault();
}
答案 4 :(得分:0)
var one = from c in data.actions
where c.actionType == Action.ActionTypeOne
|| c.actionType == Action.ActionTypeTwo
orderby c.actionType == Action.ActionTypeOne ? 0 : 1
select new Attrib
{
id = c.id,
name = c.name
}).FirstOrDefault();
等效的SQL查询将是(我使用了Case语句,因为我不知道ActionType列的数据类型):
Select TOP 1 id, name
From Actions
where ActionType In(ActionTypeOne, ActionTypeTwo)
Order By Case ActionType When 1 Then 0 Else 1 End ASC