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.Table
1.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.