Archive

Posts Tagged ‘.net’

Entity Framework 4 many-to-many

10 March 10 2010

I had another problem with EF4 today. Code that worked fine in .NET 3.5 didn’t work after I regenerated the entity model using Visual Studio 2010.

I found an answer, again on Stack Overflow: http://stackoverflow.com/questions/2243618/how-do-you-insert-or-update-many-to-many-tables-in-net-entity-framework

It turns out that the generator decided that one of my foreign keys in an associative table should have a StoredGeneratorPattern of Identity, meaning it thought it was an identity column. When it isn’t.

But updating the XML as suggested in the answer above fixed it. So that’s good.

Technology , ,

1..0 or 1 relationships in Entity Framework

9 March 9 2010

I came across this problem today when migrating a project from VS 2008/.NET 3.5 to VS 2010 RC1/.NET 4.0. I don’t actually think it’s a VS 2010 thing, though.

I have two entities A and B. There is a navigation property on A, and it can have either one or no instances of B. B’s foreign key is to A’s primary key (obviously) but B also has its own primary key. In the database, B has a unique index on that foreign key column, which will enforce the rule.

The problem when upgrading to VS 2010 occurred because I clicked the “Include foreign key columns in the model” check box when generating the model from the database. (I regenerated it because the tools might be better in 2010 so figured I should start from scratch.) That’s where my problem came from. The entity model designer wouldn’t let me change the navigation property and associated relationship from 1..* to 1..0 or 1, because the relationship had to be between the entities’ keys for that to work.

The problem only happens when you generate the model with foreign keys as their own columns. I regenerated it so that foreign key columns weren’t generated (the foreign keys were represented only as their navigation properties) and it worked fine, as it did in VS 2008.

I found this answer here: http://stackoverflow.com/questions/2141328/unique-keys-not-recognized-by-entity-framework/2326859#2326859

Hopefully this might be of some help to someone else!

Technology , , ,

AJAX history with ASP.NET AJAX 1.0

27 March 27 2009

If you are still using the original ASP.NET AJAX 1.0 release, you may be looking for a way to use .NET 3.5 SP1’s “history” feature of the ScriptManager control.

A while back, Nikhil Kothari wrote a component called UpdateHistory, which looks like what was integrated into 3.5 SP1. It certainly solved my problem.

Combine it with HttpUtility.ParseQueryString and you’re onto a winner!

Technology , ,

Entity Framework: Part 2

17 November 17 2008

I have been reading a bit of the documentation about the ADO.NET Entity Framework. There are a few passages that relate to my previous post:

Because referenced objects are not automatically loaded, you must call the Load method on the entity reference to load the related object data into the object context. You can also specify a query path that defines which related objects to load with returned objects. For more information, see Querying Data as Objects (Entity Framework).

A query path definition ensures that the Course objects related to Department objects are also returned.

The code accompanying this is:

// Define a query that returns all Department objects and related
// Course objects, ordered by name.
ObjectQuery<Department> departmentQuery =
    schoolContext.Department.Include("Course").OrderBy("it.Name");

Another difference between LINQ to SQL and using the Entity Framework is that the SubmitChanges() method’s equivalent is the SaveChanges() method.

So I managed to solve my original problem of not being able to follow references in related tables/objects by using the Include method when performing my queries:

My first test method from the last post, TestFooHasTwoBars() will pass when it’s written like this (new code is highlighted):

[TestMethod]
public void TestFooHasTwoBars()
{
    testlinqEntities entities = new testlinqEntities();
    Foo foo = (from f in entities.Foo.Include("Bar") where f.FooId == 1 

        select f).First();
    Assert.IsNotNull(foo);
    Assert.AreEqual(2, foo.Bar.Count);
}

I’m not sure if there’s a way to do that in "pure" LINQ (ie without having to include the string to reference the Bar property.

Technology , ,

LINQ to Entities – my first steps

14 November 14 2008

I have had little bit of experience with LINQ to SQL, but recently read that Microsoft is instead concentrating on LINQ to Entities. I have just started a new project, so thought decided to use LINQ to Entities instead. And I ran into a problem. I haven’t managed to find a solution to it yet, so I figured that I would write about it here and hopefully, once I have figured out what I was doing wrong, it might be able to help someone else out.

The problem is that I have a site using ASP.NET MVC (though that’s not really relevant) that uses the normal ASP.NET SQL membership provider. Then I have a table that has a foreign key reference to the aspnet_Users table:

So far, so good. I have created a user, and manually created a Foo and given it two Bars.

Now I create the ADO.NET Entity Data Model, generated from the database. I only want three tables in my model: aspnet_Users, Foo and Bar.

Not a lot is different there. In the end I want aspnet_Users to just be called User, but let’s just see if this is working out of the box. My prediction (based on how it actually worked in my real project, is that the reference between Bars and Foos is fine, but between Users and Foos will not work. Let’s see…

[TestMethod]
public void TestFooExists()
{
    testlinqEntities entities = new testlinqEntities();
    Foo foo = (from f in entities.Foo select f).First();
    Assert.IsNotNull(foo);
}

That test passed.

Next is to check that the Foo who’s ID is 1 has got two Bars.

[TestMethod]
public void TestFooHasTwoBars()
{
    testlinqEntities entities = new testlinqEntities();
    Foo foo = (from f in entities.Foo where f.FooId == 1 select f).First();
    Assert.IsNotNull(foo);
    Assert.AreEqual(2, foo.Bar.Count);
}


This is a bit of a surprise. It failed. I can’t think why. Let’s check to see whether the first Bar has got a Foo:

[TestMethod]
public void TestBarHasAFoo()
{
    testlinqEntities entities = new testlinqEntities();
    Bar bar = (from b in entities.Bar select b).First();
    Assert.IsNotNull(bar, "Could not find a Bar.");
    Assert.IsNotNull(bar.Foo, "Bar has no Foo.");
}

No, that failed too. So none of the references are working. They worked out of the box with LINQ to SQL.

For good measure, I’ll write two more tests:


[TestMethod]
public void TestFooHasUser()
{
    testlinqEntities entities = new testlinqEntities();
    Foo foo = (from f in entities.Foo where f.FooId == 1 select f).First();
    Assert.IsNotNull(foo);
    Assert.IsNotNull(foo.aspnet_Users);
}

[TestMethod]
public void TestUserHasAFoo()
{
    testlinqEntities entities = new testlinqEntities();
    Guid userId = new Guid("8c3efb04-80aa-4b6b-af11-98445a08f4ea");
    aspnet_Users user = (from u in entities.aspnet_Users where 

        u.UserId == userId select u).First();
    Assert.IsNotNull(user);
    Assert.IsTrue(user.Foo.Count > 0);
}

These failed too. As expected.

So, I am quite surprised that none of the relationships are actually working. Was it a fluke that they worked earlier?

No, I wrote another test, that gets a Bar’s Foo’s User’s ID:


[TestMethod]
public void TestGetUserIdOfFooOfBar()
{
    Guid expectedUserId = new Guid("8c3efb04-80aa-4b6b-af11-98445a08f4ea");
    testlinqEntities entities = new testlinqEntities();
    Guid userId = (from b in entities.Bar where b.BarId == 1 

        select b.Foo.aspnet_Users.UserId).First();
    Assert.AreEqual<Guid>(expectedUserId, userId);
}

And that one passes.

So, while in LINQ to SQL you could keep on following references after you had performed your original query, you can’t do that with LINQ to Entities. Well, not automatically, at least. That’s a bit of a disappointment. That means more work for me.

I just had a look at the Foo.Bar property. There is an IsLoaded property and a Load() method. If you Load() the Bar first, then the count works. LINQ to SQL didn’t need such as method, I guess, because it was always working against the database. I should probably read up more on this. It doesn’t seem right to call Load() which will probably load all of the properties of the "child" objects, when I only need one of those properties, or only need the first one.

I will investigate further and hopefully remember to post a followup.

But in summary, the IRelatedEnd.Load() method (the EntityCollection class derives from RelatedEnd which implements IRelatedEnd – sorry I can’t be bothered with the namespaces). It’s that method that will load the collection’s contents. That’s for one-to-many relationships. For the many-to-one and one-to-one side of things, I used, for example, Bar.FooReference.Load(). (FooReference is of type EntityReference<Foo>, which ultimately derives from RelatedEnd as well).

Technology , , ,

I like LINQ

18 November 18 2007

LINQ stands for Language Integrated Query, a new feature of the .NET Framework 3.5. And it’s cool.

I have used LINQ to SQL on the My Flatmates Facebook application, and it made things a lot quicker. LINQ to SQL creates classes out of your database tables. Then you can use LINQ statements to create instances of the classes from your data. I think that Ruby is similar in that you work directly against the database. But I’ve never worked with Ruby before and haven’t read anything about it (I think Siggy from SilverStripe told me about it, discussing the performance of PHP vs the ease of Ruby, but I digress).

It requires a change of thinking though. I’ve grown up believing that stored procedures are the way to go, for performance and security. But LINQ to SQL is more flexible when you don’t use stored procs. I did a bit of a search for what this means for best practice and it seems that best practice is changing. (And in the MySQL world, stored procs are only a new thing and most people don’t think they’re needed.)

That is why I like LINQ.

Technology , , ,