0

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.

RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • well, first and foremost, `0x3` is absolutely **not** the correct value, unless you mean for `CommentsUser` to represent the union between `User` and `Comments` which I suspect you actually do not want. – Kirk Woll Oct 06 '10 at 00:24
  • What do you mean, you cannot have commentsuser without comments? – John Gardner Oct 06 '10 at 00:24
  • @Kirk Woll - no, that is not what i want. As i said, i have no experience with enum flags - i don't know what values to use for the flags. At this stage im going with an array of PostAssociations (as opposed to the flags), unless someone comes up with an answer. – RPM1984 Oct 06 '10 at 00:25
  • @John Gardner - correct. "Comments.User" cannot be supplied unless "Comments" is also supplied (as .User is a sub-set of .Comments). – RPM1984 Oct 06 '10 at 00:26

2 Answers2

2

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
  • 24,225
  • 5
  • 58
  • 76
  • 1
    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 Oct 06 '10 at 00:28
  • 1
    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 S. Oct 06 '10 at 00:41
0

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
  • 72,246
  • 58
  • 225
  • 350
  • For usability your FindSingle() method could be implemented as FindSingle(int id, params PostAssociations[] args) – cordialgerm Oct 06 '10 at 02:21