views:

93

answers:

2

Hi Guys,

I have the following enum:

[Flags]
public enum PostAssociations
{
    None = 0x0,
    User = 0x1,
    Comments = 0x2,
    CommentsUser = 0x3
}

As a starting note, im not sure if those flags are correct.

I'm doing this so that i have a fluent way of defining "Includes" for Entity Framework (as the EF Include method takes a string, which i dont want exposed to the UI).

So i want it so my service layer can accept a PostAssociations, and in my service layer i utilize an extension method to convert this to a string[]. (which my repo then splits up in order to do the .Include).

I haven't done much with Flags Enum's, so i apologize for my ignorance. :)

This is a "truth-table" of what i want (enum value, transformed string[])

None = null
User = new string[] { "User" }
Comments = new string[] { "Comments" }
User, Comments = new string[] { "User", "Comments" }
Comments, CommentsUser = new string[] { "Comments", "Comments.User" }
User, Comments, CommentsUser = new string[] { "User", "Comments", "Comments.User" }

Cannot have CommentsUser without Comments.

So i need help with three things:

  1. How to setup the enum to match that truth table?
  2. How do i call the service layer for one of those examples?
  3. How do i write an extension method to convert that enum to the string array?

Of course, if you guys can think of a better way to do what im trying to do, i'll consider that too. Essentially i'm trying to mask away the "magic strings" of the EF Include behind an Enum, and considering you can do multiple includes (or none), i thought this was a good case for a Flags Enum.

Thanks guys.

+2  A: 

if you created the enum with flags:

[Flags]
public enum PostAssociations
{    
    None = 0x0,
    User = 0x1,
    Comments = 0x2,
    CommentsUser = User|Comments,
}

that would make more sense. In your current code i don't understand what you're trying to achieve.

otherwise, i don't think you want a flag based enum at all...

John Gardner
Yep, i dont think i should be using flag enums here. What you've proposed makes sense, but not in my scenario (because i havent explained it properly). CommentsUser is a seperate value (not User + Comments). Therefore i don't think i should be using flags. Im going to stick with an PostAssociations[].
RPM1984
You can use bitwise operators on any enum assuming they are powers of two. You don't need the flags attribute unless you want ToString to work nicely (there are a couple of other features that go along with it but I don't remember).
Ed Swangren
A: 

My bad guys, my inexperience with flags enums has resulted in a confusing question.

My scenario isn't valid for flags enum.

Instead, i have opted to use a PostAssociations[].

My service layer:

public Post FindSingle(int postId, PostAssociations[] postAssociations)
{
   return repo.Find(postAssocations.ToEfInclude()).WithId(postId);
}

The extension method:

public static string[] ToEfInclude(this PostAssociations[] postAssocations)
{
    if (postAssocations == null) return null;

    List<string> includeAssociations = new List<string>();

    if (postAssocations.Contains(PostAssociations.User))
        includeAssociations.Add("User");
    if (postAssocations.Contains(PostAssociations.Comments))
    {
        if (postAssocations.Contains(PostAssociations.CommentsUser))
        {
            includeAssociations.Add("Comments.User");   
        }

        includeAssociations.Add("Comments");
    }

    return includeAssociations.ToArray();
}

Usage:

PostAssociations[] associations = new[] { PostAssociations.Comments, PostAssociations.User, PostAssociations.CommentsUser };    
return service.Find(1, associations);
RPM1984
For usability your FindSingle() method could be implemented as FindSingle(int id, params PostAssociations[] args)
erash