tags:

views:

27

answers:

0

I am trying to use compiled queries for my data access code in an asp.net application. The code I am using for updates is shown below.

    public void Update(IFoo item)
    {
        using (SqlConnection connection = GetConnection())
        using(FooDataContext dc = new FooDataContext(connection))
        {
            FooData data = FooDataContext.GetFooByName(dc, item.Name).FirstOrDefault();

            dc.Foos.Attach(data);

            //FooData data = (from f in dc.Foos
              //                   where f.Name == item.Name
                //                 select f).FirstOrDefault();

            data.Description = item.Description;
            data.Type = item.Type;

            dc.SubmitChanges();
        }
    }

Now the problem is that the very first time this method is called in the app domain of the web app it errors with:

System.InvalidOperationException: Cannot attach an entity that already exists. at System.Data.Linq.Table1.Attach(TEntity entity, Boolean asModified) at System.Data.Linq.Table1.Attach(TEntity entity)

Which I understand, but every subsiquent call will complete successfully and update the database with the Attach() call in place. If I remove the Attach() call then the opposite occurrs - the very first call in a cold app domain succeeds but every subsiquent call does not update the database and no error appears in the logs.

If the commented code that doesn't use a compiled query is run then no Attach is every required and the code functions correctly on every method call.

Is there something I am missing in the use of a compiled query? DataContext is below:

public class GlobalCategoriesDataContext : DataContext
{
    static readonly DataLoadOptions FoosWithAssociatedBars = (new Func<DataLoadOptions>(() =>
    {
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith<FooData>(c => c.AssociatedBars);
        return dlo;
    }))();


    //compiled query
    public static Func<FooDataContext, IQueryable<FooData>>
                AllFoos =
                        CompiledQuery.Compile((FooDataContext context)
                                     => from c in context.Foos
                                        select c);


    public static Func<FooDataContext, string, IQueryable<FooData>>
                GetFooByName =
                        CompiledQuery.Compile((FooDataContext context, string name)
                                    => from c in context.Foos
                                       where c.Name == name
                                       select c);


    public Table<FooData> Foos;
    public Table<BarData> Bars;


    public FooDataContext(SqlConnection connection)
        : base(connection)
    {
        Foo = this.GetTable<FooData>();
        Bar = this.GetTable<BarData>();

        this.LoadOptions = FooWithAssociatedBar;
    }
}

Thanks ahead of time.