Such code is used in C # to specify the name of the property without the risk of being sealed. In classic code, this might look like this:
modelBuilder.Entity<Customer>() .Property("FirstName") .IsRequired() .HasMaxLength(30);
It is clear that when you rename the FirstName property, the code continues to compile, but stops working at run time. It would be nice to use such a construction that, when renaming a property, would lead to a compilation error. This would enable us to immediately detect and correct typos in the field names.
Just for this and apply the syntax based on expression trees:
public PrimitivePropertyConfiguration Property<T>( Expression<Func<TStructuralType, T>> propertyExpression ) where T : struct, new() { . . . }
The syntax is scary, but it allows you to statically typify the call to any class property. What happens in this case?
Func<TStructuralType, T> means that a lambda expression is expected at the input, it is an anonymous ( nameless ) function. The syntax of such functions in C # looks like x => Exp(x) , where x is a function parameter, and Exp(x) is some kind of not very complicated expression. In our case, this simple expression is an appeal to the property of the object.
Expression<Func<TStructuralType, T>> means that we will not perform the function directly, but instead build the expression tree and store it in a variable of type Expression .
An object of this class will be available at runtime and we will be able to walk through it and retrieve the name of the property.
The fact that this Expression is from Func<TStructuralType, T> limits the way of setting the propertyExpression parameter: we are waiting for either the function name with one parameter or the anonymous function with one parameter (also known as lambda).
Simply put, Expression<Func<TStructuralType, T>> means that when you call Property , something like x => Exp(x) is expected as a parameter. You can still shoot yourself in the foot and write an inappropriate expression, for example, x => x + x , but you shouldn’t do it anyway.
Finally, what is the main magic, how is the Property method arranged? The basis, of course, is reflection and details can be found in the answer to the corresponding question on StackOverflow (English) .
Directly in the Entity Framework, methods that retrieve the name of a property from an expression are moved to the ExpressionExtensions class.