Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to put @ in front of `Name` in an object initializer?

Purely curiosity at this point since the @ fixed the problem I was having, but why is Name special?

I have an EF entity property called Name…if I don't put the @ in front of Name, I don't get any kind of error, but the Name property on the object doesn't get assigned. If I put @Name in the object initializer, it assigns Name properly:

a = new Author
{
    Id = Guid.NewGuid().ToString(),
    @Name = "Jason Hater" // Apparently "Name" is quasi-reserved or something...?!?
};

I checked the generated code, and it's just named Name:

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public global::System.String Name
{
    get
    {
        return _Name;
    }

    //...
}

So, Name isn't listed as a keyword, so why is it special?

Edit

Okay, as @sergey suggested, it's definitely a little more complicated than I first thought. Something goofy about Entity Framework specifically.

This is manifesting inside a unit testing class, that may be relevant also. I'm unsure what's relevant and what's not now unfortunately, so here's the whole [TestInitialize] method, and at the bottom of it you can see that the weirdness happens around context.SaveChanges():

[TestClass]
public class EntityConverterTests
{
    private Author a;
    private Post p, p2, p3;

    [TestInitialize]
    public void SetupEntities()
    {
        TestEntities context = new TestEntities();

        // Clear it out!
        foreach (Comment o in context.Comments) context.Comments.DeleteObject(o);
        foreach (Post o in context.Posts) context.Posts.DeleteObject(o);
        foreach (Author o in context.Authors) context.Authors.DeleteObject(o);
        context.SaveChanges();

        a = new Author
        {
            Id = Guid.NewGuid().ToString(),
            Name = "Jason Hater"
        };
        context.Authors.AddObject(a);

        System.Diagnostics.Debug.WriteLine(a.Name); // "Jason Hater"…Yay!

        // probably irrelevant from here until context.SaveChanges()…?

        p = new Post()
        {
            Title = "Linkbait!",
            Author = a
        };
        p2 = new Post
        {
            Title = "Rant #1023",
            Author = a
        };
        p3 = new Post
        {
            Title = "Polemic in E-flat minor #824",
            Author = a
        };

        a.Posts.Add(p);
        a.Posts.Add(p2);
        a.Posts.Add(p3);

        p.Comments.Add(
            new Comment()
            {
                Body = "Nuh uh!",
                Post = p
            }
        );
        p.Comments.Add(
            new Comment()
            {
                Body = "Yeah huh!",
                Post = p
            }
        );
        p.Comments.Add(
            new Comment()
            {
                Body = "Third Reich.",
                Post = p
            }
        );

        p2.Comments.Add(
            new Comment
            {
                Body = "I laughed, I cried!",
                Post = p2
            }
        );

        System.Diagnostics.Debug.WriteLine(a.Name); // "Jason Hater"…great!

        context.SaveChanges();

        System.Diagnostics.Debug.WriteLine(a.Name); // a.Name is null -> empty string!
    }

    // …

}

More coming, because now the @ isn't "fixing" it--that is now I'm still seeing null in the test method I was seeing it correct before…something in another [TestMethod] may have been making a difference, perhaps…unsure, still investigating. Still, why is the change around context.SaveChanges() occurring?

Edit 2

Uh, okay…somehow the StoreGeneratedPattern property on my Name property was set to "Identity" in the modeling GUI. No idea how that happened. Changing it to "None" may have eliminated my problem. But…I know I hadn't changed that back when I thought the @ symbol had fixed it…something still odd here.

Edit 3

One way or the other, the bad value for StoreGeneratedPattern was the cause of my assignment/saving problem. I'm unsure why I observed success one or more times with that setting, but the original question is no longer the correct question.

like image 963
S'pht'Kr Avatar asked Feb 24 '14 12:02

S'pht'Kr


1 Answers

In C# the @ is used if you want turn a keyword into an identifier. Since Name is no keyword, it has no effect at all.

This is purely a C# rule, at the IL level the @ won't be present anymore, even if the name of the identifier matches a C# keyword. So it is impossible for Entity Framework to detect the difference.

like image 86
Loki Avatar answered Sep 18 '22 12:09

Loki