Mock same method in a test using Moq with different linq expressions - linq

I have a repository with this method
public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>,
IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
I have a method that is using it as such to get a user to work on
var user = this.applicationUserRepository.Get(x => x.EmailAddress == userName).FirstOrDefault();
It then calls the same method with a different expression further in the method as follows to check the user working on the first user
var changingUser = this.applicationUserRepository.Get(x => x.Id == changingUserId).FirstOrDefault();
I am trying to mock the repository with two setups to call it twice in the same test.
string emailAddress = "myaddresss#test.com";
int changingUserId = 5;
var targetUsers = new List<ApplicationUser>
{
new ApplicationUser { Id = 1, Password = "Testing123", EmailAddress = emailAddress }
};
// Setup the user that will be modified to be found
var mockApplicationUserRepository = new Mock<IRepository<ApplicationUser>>();
mockApplicationUserRepository
.Setup(aur => aur.Get(x => x.EmailAddress == userName, null, string.Empty))
.Returns(targetUsers.AsEnumerable());
// Set up to query the changing user to not be found
mockApplicationUserRepository
.Setup(aur2 => aur2.Get(x => x.Id == changingUserId, null, string.Empty))
.Returns(new List<ApplicationUser>().AsEnumerable()); // Empty list
Even though the second call will never be hit, for this test, I want to learn how to set this up.
When I run the test the first call
var user = this.applicationUserRepository.Get(x => x.EmailAddress == userName).FirstOrDefault();
I get null
If I change the mock to have
It.IsAny<Expression<Func<ApplicationUser, bool>>>()
I get the expected user back.
I can not figure out how I will set the two calls up so it will know which expression to use. Any help will be appreciated.

The problem is that Moq does not compare the expressions you use (only reference equality).
Using this little helper class:
public static class LambdaCompare
{
public static bool Eq<TSource, TValue>(
Expression<Func<TSource, TValue>> x,
Expression<Func<TSource, TValue>> y)
{
return ExpressionsEqual(x, y, null, null);
}
public static Expression<Func<Expression<Func<TSource, TValue>>, bool>> Eq<TSource, TValue>(Expression<Func<TSource, TValue>> y)
{
return x => ExpressionsEqual(x, y, null, null);
}
private static bool ExpressionsEqual(Expression x, Expression y, LambdaExpression rootX, LambdaExpression rootY)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
var valueX = TryCalculateConstant(x);
var valueY = TryCalculateConstant(y);
if (valueX.IsDefined && valueY.IsDefined)
return ValuesEqual(valueX.Value, valueY.Value);
if (x.NodeType != y.NodeType
|| x.Type != y.Type) return false;
if (x is LambdaExpression)
{
var lx = (LambdaExpression) x;
var ly = (LambdaExpression) y;
var paramsX = lx.Parameters;
var paramsY = ly.Parameters;
return CollectionsEqual(paramsX, paramsY, lx, ly) && ExpressionsEqual(lx.Body, ly.Body, lx, ly);
}
if (x is MemberExpression)
{
var mex = (MemberExpression) x;
var mey = (MemberExpression) y;
return Equals(mex.Member, mey.Member) && ExpressionsEqual(mex.Expression, mey.Expression, rootX, rootY);
}
if (x is BinaryExpression)
{
var bx = (BinaryExpression) x;
var by = (BinaryExpression) y;
return bx.Method == #by.Method && ExpressionsEqual(bx.Left, #by.Left, rootX, rootY) &&
ExpressionsEqual(bx.Right, #by.Right, rootX, rootY);
}
if (x is ParameterExpression)
{
var px = (ParameterExpression) x;
var py = (ParameterExpression) y;
return rootX.Parameters.IndexOf(px) == rootY.Parameters.IndexOf(py);
}
if (x is MethodCallExpression)
{
var cx = (MethodCallExpression)x;
var cy = (MethodCallExpression)y;
return cx.Method == cy.Method
&& ExpressionsEqual(cx.Object, cy.Object, rootX, rootY)
&& CollectionsEqual(cx.Arguments, cy.Arguments, rootX, rootY);
}
throw new NotImplementedException(x.ToString());
}
private static bool ValuesEqual(object x, object y)
{
if (ReferenceEquals(x, y))
return true;
if (x is ICollection && y is ICollection)
return CollectionsEqual((ICollection) x, (ICollection) y);
return Equals(x, y);
}
private static ConstantValue TryCalculateConstant(Expression e)
{
if (e is ConstantExpression)
return new ConstantValue(true, ((ConstantExpression) e).Value);
if (e is MemberExpression)
{
var me = (MemberExpression) e;
var parentValue = TryCalculateConstant(me.Expression);
if (parentValue.IsDefined)
{
var result =
me.Member is FieldInfo
? ((FieldInfo) me.Member).GetValue(parentValue.Value)
: ((PropertyInfo) me.Member).GetValue(parentValue.Value);
return new ConstantValue(true, result);
}
}
if (e is NewArrayExpression)
{
var ae = ((NewArrayExpression) e);
var result = ae.Expressions.Select(TryCalculateConstant);
if (result.All(i => i.IsDefined))
return new ConstantValue(true, result.Select(i => i.Value).ToArray());
}
return default(ConstantValue);
}
private static bool CollectionsEqual(IEnumerable<Expression> x, IEnumerable<Expression> y, LambdaExpression rootX, LambdaExpression rootY)
{
return x.Count() == y.Count()
&& x.Select((e, i) => new {Expr = e, Index = i})
.Join(y.Select((e, i) => new { Expr = e, Index = i }),
o => o.Index, o => o.Index, (xe, ye) => new { X = xe.Expr, Y = ye.Expr })
.All(o => ExpressionsEqual(o.X, o.Y, rootX, rootY));
}
private static bool CollectionsEqual(ICollection x, ICollection y)
{
return x.Count == y.Count
&& x.Cast<object>().Select((e, i) => new { Expr = e, Index = i })
.Join(y.Cast<object>().Select((e, i) => new { Expr = e, Index = i }),
o => o.Index, o => o.Index, (xe, ye) => new { X = xe.Expr, Y = ye.Expr })
.All(o => Equals(o.X, o.Y));
}
private struct ConstantValue
{
public ConstantValue(bool isDefined, object value) : this()
{
IsDefined = isDefined;
Value = value;
}
public bool IsDefined { get; private set; }
public object Value { get; private set; }
}
}
you can setup your mock like this:
Expression<Func<ApplicationUser, bool>> expr = x => x.EmailAddress == emailAddress;
var mockApplicationUserRepository = new Mock<IRepository<ApplicationUser>>();
mockApplicationUserRepository
.Setup(aur => aur.Get(It.Is<Expression<Func<ApplicationUser, bool>>>(x => LambdaCompare.Eq(x, expr)), null, string.Empty))
.Returns(targetUsers.AsEnumerable());

Just adding a comment to this old answer (though quite useful code)
This version of LambdaCompare class is missing a case to compare an UnaryExpression, something which is included in the code in the original post.
Use that code instead of this (I learnt the hard way...)

Related

What is the difference when converting the Linq result to ToList() and when not converting it toList

In the below example when I donot use .ToList() in the Line - var b = a.SelectMany(x => a.Select(y => { ans.Add(new Tuple<int, int>(x, y)); return false; })).ToList();
The Count of ans is 0
Can someone explain what exactly happening here with and without .ToList();
public void selectAll()
{
var ans = new List<Tuple<int, int>>();
var a = new List<int>()
{
1,2,3
};
var b = a.SelectMany(x => a.Select(y => { ans.Add(new Tuple<int, int>(x, y)); return false; })).ToList();
foreach (var item in ans)
{
Console.WriteLine($"{item.Item1},{item.Item2}");
}
}
Don't use side effects use something like this:
var a = Enumerable.Range(1, 3);
var ans = a.Select(x => a.Select(y => new Tuple<int, int>(x, y))).SelectMany(z => z);
foreach (var item in ans)
{
Console.WriteLine($"{item.Item1},{item.Item2}");
}

XUnit Test for ViewComponent returns null result?

I am trying to test my ViewComponent with XUnit.
When I debug through the component and set a break point right before it returns the Component View, the model is set.
Here is the simple model I am returning.
public class IntDashMakeRecAssgnmntsPoRespMngrVM
{
public IEnumerable<Audit> Audits { get; set; }
}
And I am trying to assert the Audits.Count() is greater than 0.
Here is my View Component:
public class IntDashMakeRecAssgnmntsPoRespMngrViewComponent : ViewComponent
{
private IAuditRepository _auditRepo;
private IExternalRepository _externalRepo;
public IntDashMakeRecAssgnmntsPoRespMngrViewComponent(IAuditRepository auditRepo,
IExternalRepository externalRepo)
{
_auditRepo = auditRepo;
_externalRepo = externalRepo;
}
public IViewComponentResult Invoke()
{
ClaimsPrincipal user = HttpContext.Request.HttpContext.User;
short staffId = short.Parse(user.Claims.Single(c => c.Type == "StaffId").Value);
// Get all Internal Audits that are not closed and not completed
var audits = _auditRepo.Audits
.Include(a => a.Findings).ThenInclude(f => f.Recommendations).ThenInclude(r => r.Assignments)
.Where(a => a.StatusID != 3 && a.StatusID != 11);
var external = _externalRepo.ExternalRecords;
audits = audits.Where(a => !external.Any(e => e.AuditID == a.AuditID));
if (User.IsInRole("PAG_SPEC") && !User.IsInRole("PAG_ADMIN_INT"))
{
audits = audits.Where(a =>
a.Assignments.Any(assn => assn.AssignmentAuditId == a.AuditID
&& assn.AssignmentRoleId == 2 && assn.AssignmentStaffId == staffId));
}
// Where audit has a recommendation without an assigned PO Authorizer
// OR without an assigned Responsible Manager (Rec Level).
List<Audit> auditsToAssign = new List<Audit>();
foreach (Audit audit in audits)
{
foreach (Finding finding in audit.Findings)
{
foreach (Recommendation rec in finding.Recommendations)
{
if (!rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)
|| !rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 26)
)
{
auditsToAssign.Add(rec.Finding.Audit);
break;
}
}
}
}
IntDashMakeRecAssgnmntsPoRespMngrVM intDashMakeRecAssgnmntsPoRespMngrVM =
new IntDashMakeRecAssgnmntsPoRespMngrVM
{
Audits = auditsToAssign
};
return View("/Views/InternalAudit/Components/Dashboard/IntDashMakeRecAssgnmntsPoRespMngr/Default.cshtml", intDashMakeRecAssgnmntsPoRespMngrVM);
}
}
When I get to this line in debugging and break to inspect, I have 1 Audit which I want:
return View("/Views/InternalAudit/Components/Dashboard/IntDashMakeRecAssgnmntsPoRespMngr/Default.cshtml", intDashMakeRecAssgnmntsPoRespMngrVM);
Now here is my Unit Test:
[Fact]
public void ReturnsAudit_1Finding_1Rec_1Asgn_PONeeded_RespMnrAssigned()
{
// Arrange
var audits = new Audit[]
{
new Audit { AuditID = 1 }
};
var findings = new Finding[]
{
new Finding{ Audit = audits[0], FindingId = 1 } // 1 Finding
};
var recommendations = new List<Recommendation>()
{
new Recommendation // 1 Rec
{
Finding = findings[0],
Assignments = new List<Assignment>()
{
// PO Authorizor
new Assignment { AssignmentRoleId = 15 }
// No Responsible Manager
}
}
};
audits[0].Findings = findings;
findings[0].Recommendations = recommendations;
Mock<IAuditRepository> mockAuditRepo = new Mock<IAuditRepository>();
mockAuditRepo.Setup(m => m.Audits).Returns(audits.AsQueryable());
Mock<IExternalRepository> mockExternalRepo = new Mock<IExternalRepository>();
mockExternalRepo.Setup(m => m.ExternalRecords).Returns(
new External[0].AsQueryable()
);
// Act
var component = new IntDashMakeRecAssgnmntsPoRespMngrViewComponent(
mockAuditRepo.Object, mockExternalRepo.Object);
component.ViewComponentContext = new ViewComponentContext();
component.ViewComponentContext.ViewContext.HttpContext = TestContext;
var result =
component.Invoke() as IntDashMakeRecAssgnmntsPoRespMngrVM;
int auditCount = (result).Audits.Count();
// Assert
Assert.Equal(1, auditCount);
}
Why is result null on this line?
var result =
component.Invoke() as IntDashMakeRecAssgnmntsPoRespMngrVM;
I also tried this first and it is still null:
ViewComponentResult result =
component.Invoke() as ViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.Model).Audits.Count();
I figured it out.
I wasn't casting the result to the right type.
I had this:
ViewComponentResult result =
component.Invoke() as ViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.Model).Audits.Count();
It should be this:
var result =
component.Invoke() as ViewViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.ViewData.Model).Audits.Count();
ViewViewComponentResult instead of ViewComponentResult.

LINQ query fails with nullable variable ormlite

I'm trying to write following LINQ query using ServiceStack Ormlite.
dbConn.Select<Product>(p => p.IsActive.HasValue && p.IsActive.Value)
Here, Product is my item class and "IsActive" is Nullable Bool property in that class. When this line executes it always throws "InvalidOperationException" with the message
variable 'p' of type '' referenced from scope '', but it is not defined
I tried different variants as following but still same exception result
dbConn.Select<Product>(p => p.IsActive.HasValue == true && p.IsActive.Value == true)
dbConn.Select<Product>(p => p.IsActive != null && p.IsActive.Value == true)
But if I just write
dbConn.Select<Product>(p => p.IsActive.HasValue)
then it works.
I'm puzzled what is the problem? Is this servicestack ormlite issue?
My answer can handle Nullable value like "value" and "HasValue" with servicestack ormlite. And But also with datetime nullable ,like 'createdate.value.Year'.
you must change two place.
modify VisitMemberAccess method:
protected virtual object VisitMemberAccess(MemberExpression m)
{
if (m.Expression != null)
{
if (m.Member.DeclaringType.IsNullableType())
{
if (m.Member.Name == nameof(Nullable<bool>.Value))
return Visit(m.Expression);
if (m.Member.Name == nameof(Nullable<bool>.HasValue))
{
var doesNotEqualNull = Expression.NotEqual(m.Expression, Expression.Constant(null));
return Visit(doesNotEqualNull); // Nullable<T>.HasValue is equivalent to "!= null"
}
throw new ArgumentException(string.Format("Expression '{0}' accesses unsupported property '{1}' of Nullable<T>", m, m.Member));
}
if (m.Member.DeclaringType == typeof(DateTime))
{
var ExpressionInfo = m.Expression as MemberExpression;
if (ExpressionInfo.Member.DeclaringType.IsNullableType())
{
if (ExpressionInfo.Member.Name == nameof(Nullable<bool>.Value))
{
var modelType = (ExpressionInfo.Expression as MemberExpression).Expression.Type;
var tableDef = modelType.GetModelDefinition();
var columnName = (ExpressionInfo.Expression as MemberExpression).Member.Name;
var QuotedColumnName = GetQuotedColumnName(tableDef, columnName);
if (m.Member.Name == "Year")
{
return new PartialSqlString(string.Format("DATEPART(yyyy,{0})", QuotedColumnName));
}
if (m.Member.Name == "Month")
return new PartialSqlString(string.Format("DATEPART(mm,{0})", QuotedColumnName));
}
if (ExpressionInfo.Member.Name == nameof(Nullable<bool>.HasValue))
{
var doesNotEqualNull = Expression.NotEqual(ExpressionInfo.Expression, Expression.Constant(null));
return Visit(doesNotEqualNull); // Nullable<T>.HasValue is equivalent to "!= null"
}
}
else
{
var modelType = ExpressionInfo.Expression.Type;
var tableDef = modelType.GetModelDefinition();
var columnName = ExpressionInfo.Member.Name;
var QuotedColumnName = GetQuotedColumnName(tableDef, columnName);
if (m.Member.Name == "Year")
return new PartialSqlString(string.Format("DATEPART(yyyy,{0})", QuotedColumnName));
if (m.Member.Name == "Month")
return new PartialSqlString(string.Format("DATEPART(mm,{0})", QuotedColumnName));
}
}
if (m.Expression.NodeType == ExpressionType.Parameter || m.Expression.NodeType == ExpressionType.Convert)
{
var propertyInfo = (PropertyInfo)m.Member;
var modelType = m.Expression.Type;
if (m.Expression.NodeType == ExpressionType.Convert)
{
var unaryExpr = m.Expression as UnaryExpression;
if (unaryExpr != null)
{
modelType = unaryExpr.Operand.Type;
}
}
var tableDef = modelType.GetModelDefinition();
if (propertyInfo.PropertyType.IsEnum)
return new EnumMemberAccess(
GetQuotedColumnName(tableDef, m.Member.Name), propertyInfo.PropertyType);
return new PartialSqlString(GetQuotedColumnName(tableDef, m.Member.Name));
}
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
return getter();
}
modify VisitLambda method :
protected virtual object VisitLambda(LambdaExpression lambda)
{
if (lambda.Body.NodeType == ExpressionType.MemberAccess && sep == " ")
{
MemberExpression m = lambda.Body as MemberExpression;
if (m.Expression != null)
{
string r = VisitMemberAccess(m).ToString();
if (m.Member.DeclaringType.IsNullableType())
return r;
return string.Format("{0}={1}", r, GetQuotedTrueValue());
}
}
return Visit(lambda.Body);
}
This is nature of the Linq. In order to achieve what you need, you will need to use two where closes:
dbConn.Where<Product>(p => p.IsActive.HasValue).Where(p=>p.Value==true);

how to modify or insert where into expression tree

by default I have this:
Expression<Func<ItemGroup, ItemGroupView>> Exp =
m => new ItemGroupView{
ID = m.id,
Name = m.name,
TotalCount = m.groupDetail.Sum(n => n.item.itemDetail.Count())
};
but in the runtime, I might want to add multiple filter. So for example, if I specify the status to 1 and category to mineral then it becomes
Expression<Func<ItemGroup, ItemGroupView>> Exp =
m => new ItemGroupView{
ID = m.id,
Name = m.name,
TotalCount = m.groupDetail.Sum(
n => n.item.itemDetail
.Where(o => o.status == 1 && o.category == "mineral")
.Count())
};
// ItemGroup.groupDetail is collection of ItemGroupDetail (n)
// ItemGroupDetail.item is Item
// Item.itemDetail is collection of ItemDetail (o)
// ItemDetail.item is Item
how do I modify the expression tree to insert multiple Where dynamically?
So far I do the default like this
private int _status;
private string _category;
internal Expression<Func<ItemDetail, bool>> whereStatus()
{
return o => o.status == _status;
}
internal Expression<Func<ItemDetail, bool>> whereCategory()
{
return o => o.category == _category ;
}
internal Expression<Func<ItemGroup, ItemGroupView>> GetEx()
{
return m => new ItemGroupView{
ID = m.id,
Name = m.name,
TotalCount = m.groupDetail.Sum(n => n.item.itemDetail.Count())
};
}
internal IQueryable<ItemGroupView> GetSelectQuery(IQueryabe<ItemGroup> ie)
{
ParameterExpression m = Expression.Parameter(typeof(ItemGroup), "m");
ParameterExpression n = Expression.Parameter(typeof(ItemGroupDetail), "n");
MemberInitExpression ex = (MemberInitExpression)GetEx().Body;
// ParameterReplacer is inherited from ExpressionVisitor
ex = (MemberInitExpression)new ParameterReplacer(
new ParameterExpression[] { m, n }).Visit(ex);
// ? ? ? ?
// how to modify the Expression if _status or _category is supplied?
Expression<Func<ItemGroup, ItemGroupView>> el =
Expression.Lambda<Func<ItemGroup, ItemGroupView>>
(ex, new ParameterExpression { m });
return ie.Select(el);
}
EDIT:
ItemGroup.itemDetail changed to ItemGroup.groupDetail, to avoid confusion between groups and items..
If you can create an expression that represents the Where() operation, you can then paste it into your main expression using LINQKit:
Expression<Func<IQueryable<ItemDetail>, IQueryable<ItemDetail>>> whereExpression=
id => id.Where(o => o.status == 1 && o.category == "mineral");
Expression<Func<ItemGroup, ItemGroupView>> Exp =
m => new ItemGroupView
{
ID = m.id,
Name = m.name,
TotalCount =
whereExpression.Invoke(m.itemDetail)
.Sum(n => n.item.itemDetail.Count())
};
Exp = Exp.Expand();
(Don't forget that last line, it's important.)

What is the scariest LINQ function you've seen?

While working on a personal project I wanted a simple service to extract items out of Outlook and host in WCF in a "RESTful" design. In the process I came up with this rather beastly class.
What other scary linq code have people have seen?
public IQueryable<_AppointmentItem> GetAppointments(DateTime date)
{
var dayFlag = (OlDaysOfWeek)(int)Math.Pow(2, (int)date.DayOfWeek);
return
OlDefaultFolders.olFolderCalendar.GetItems<_AppointmentItem>()
.Select(a => new
{
Appointment = a,
RecurrencePattern = a.IsRecurring ?
a.GetRecurrencePattern() : null
})
.Where(a =>
a.Appointment.Start.Date <= date &&
(
(a.RecurrencePattern == null &&
a.Appointment.End.Date >= date) ||
(
a.RecurrencePattern != null &&
(
(a.RecurrencePattern.DayOfMonth == 0 ||
a.RecurrencePattern.DayOfMonth == date.Day) &&
(a.RecurrencePattern.DayOfWeekMask == 0 ||
((a.RecurrencePattern.DayOfWeekMask &
dayFlag) != 0)) &&
(a.RecurrencePattern.MonthOfYear == 0 ||
a.RecurrencePattern.MonthOfYear == date.Month)
)
)
)
)
.Select(a => a.Appointment);
}
[OperationContract()]
[WebGet(
UriTemplate = "/appointments/{year}/{month}/{day}",
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare
)]
[ContentType("text/xml")]
public XElement ListAppointments(string year, string month, string day)
{
try
{
int iYear, iMonth, iDay;
int.TryParse(year, out iYear);
int.TryParse(month, out iMonth);
int.TryParse(day, out iDay);
if (iYear == 0) iYear = DateTime.Now.Year;
if (iMonth == 0) iMonth = DateTime.Now.Month;
if (iDay == 0) iDay = DateTime.Now.Day;
var now = new DateTime(iYear, iMonth, iDay).Date; // DateTime.Now;
return GetAppointments(now).ToXml();
}
catch (System.Exception ex)
{
return new XElement("exception", ex.ToString());
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Office.Interop.Outlook;
namespace WhitedUS.ServiceModel.Office.Linq
{
public static class OutlookUtilities
{
public static IQueryable<T> GetItems<T>(
this OlDefaultFolders defaultFolderType)
{
return
new ApplicationClass()
.Session
.GetDefaultFolder(defaultFolderType)
.Items
.OfType<T>()
.AsQueryable();
}
public static XElement ToXml<T>(this IEnumerable<T> input)
{
if (input == null)
return null;
Type typ = typeof(T);
var root = XName.Get(typ.Name.Trim('_'));
return new XElement(root,
input
.Select(x => x.ToXml<T>())
.Where(x => x != null)
);
}
public static XElement ToXml<T>(this object input)
{
if (input == null)
return null;
Type typ = typeof(T);
var root = XName.Get(typ.Name.Trim('_'));
return new XElement(root,
typ.GetProperties()
.Where(p => p.PropertyType.IsValueType ||
p.PropertyType == typeof(string))
.Select(p => new { Prop = p, Getter = p.GetGetMethod() })
.Where(p => p.Getter != null)
.Select(p => new { Prop = p.Prop, Getter = p.Getter,
Params = p.Getter.GetParameters() })
.Where(p => (p.Params == null || p.Params.Count() <= 0))
.Select(p => new { Name = p.Prop.Name,
Value = p.Getter.Invoke(input, null) })
.Where(p => p.Value != null)
.Select(p => new XAttribute(XName.Get(p.Name), p.Value))
);
}
}
}
Also see: What is the worst abuse you’ve seen of LINQ syntax?
A fully LINQified RayTracer is pretty scary.
Actually, the scariest Linq query I ever saw was my first one. It was just familiar enough to make me think I understood it and just different enough to make me doubt that I really did.

Resources