Entity Framework 6 and const vs static readonly

Note: I haven’t tested this on Entity Framework Core, but I imagine the behavior is the same

Let’s say you have the following class:

public static class BlargTypes {
     public static readonly string Foo = "Bar";
}

and then you have the following LINQ query:

var result = dbContext.Blargs.Where(x => x.Blarg == BlargTypes.Foo);

then Entity Framework will generate a SQL query that looks like this:

SELECT [Id],[Blarg] FROM [Blargs] WHERE [Blarg] = @Blarg

passing in “Bar” as the parameter value for @Blarg

Now, what if the value never changes? There’s really no need for a parameterized value for @Blarg. How do you manage that?

public static class BlargTypes {
    public const string Foo = "Bar";
}

Entity Framework will generate the following query:

SELECT [Id],[Blarg] FROM [Blargs] WHERE [Blarg] = 'Foo'

In summary, if you want a parameterized query, use static readonly, otherwise use const.

Why I dislike the whole “Micro-ORMs for everything” movement

I primarily work on “B2B” applications — for the most part, these are mostly either your basic CRUD operations and fancy reports glued together with fancy business logic.

For the longest time, a technology known as ORMs made CRUD operations a gazillion times more productive — essentially, since you had objects that represented your data, and you wanted to store those objects in database records, an ORM made it stupid simple to Create, Read, Update, and Delete those objects through various technologies.

ORMs have issues though: depending on the complexity of the query, certain classes of queries are “slow”. So, technologies known as Micro-ORMs started popping up: they bypass the query generation capabilities of ORM and instead use raw SQL and then map the results back to objects.

And there-in lies the problem: Writing raw SQL for every single possible CRUD operation is a total PITA. An ORM is fine for your basic CRUD operations. Hell, an ORM is fine for the vast majority of queries an application does.

Micro-ORMs should be an optimization when performance problems arise — not a default way of thinking.

Basically, as a modern .NET developer, Entity Framework or Entity Framework Core are perfectly good tools. They make you dramatically more productive, which means you write more code, faster. Keep in mind, as a software engineer, this is EXACTLY what you are paid to do: deliver product. Dapper is also a tool. It’s a perfectly good tool. It’s suited for a different use case than Entity Framework however. Dapper allows you to drop to the bare metal where it makes sense.

Trust me, that page with a form you persist? You don’t need Dapper. A simple list? You don’t need Dapper. A page that returns a gazillion objects using a query only Satan himself would think is good? Sure, use Dapper. But for simple things? Entity Framework or another full featured ORM should be used first, and Dapper used in specific circumstances where it makes sense.

Note: This post is intended to represent my personal views, and not intended to represent the official opinion of my employer or its affiliates.

Enums, C#, and Protocol Buffers

So, in the brave new world of microservice development, there’s this fancy technology called GRPC which allows you to define RPC-based microservices using Protocol Buffers as an IDL syntax and uses HTTP/2 as a transport underneath.

Now, Protocol Buffers’ IDL syntax supports enums. However, it doesn’t allow multiple enum values in different enums in the same namespace to have the same enum value, such as:

enum MyEnum {
FOO = 1;
BAR = 2;
}

enum OtherEnum {
FOO = 1;
BAR = 2;
}

What to do, what to do? The Protobuf compiler will complain, because FOO and BAR are the same name because that isn’t compatible with C++

The suggested alternative is to prefix your enum values with the name of the enum in ALL CAPS

enum MyEnum {
MYENUM_FOO = 1;
MYENUM_BAR = 2;
}

enum OtherEnum {
OTHERENUM_FOO = 1;
OTHERENUM_BAR = 2;
}

The cool thing is that the official C# compiler for Protobuf will convert this to idiomatic C# enums:

enum MyEnum {
Foo = 1;
Bar = 2;
}

enum OtherEnum {
Foo = 1;
Bar = 2;
}