|
Hi All, Please excuse my ignorance if this has already been answered elsewhere, or I am doing something stupid or not understanding the useage (as I am new to DevForce and CodeFirst), but I am having problems getting things to to work correctly when I use any form of inheritence in my entities and try to bind to a navigation property on the UI using the code first model. I have provided the sample code below, and I am using devforce 6.1.4.0, and EntityFramework 4.2 Whenever I try to bind to just a single entity in a silverlight page, it works perfectly as expected. However when I try to reference a navigation property in the bindings it seems to blow up and provide this error when it attempts to do a second round trip to the DB to load the associated entity. It looks to me like the error is comming from within the entity framework itself, but I have had little luck being able to google much about what is really going on, and how to resolve it. I would greatly appreciate any help that anyone can give me to solve this. Silverlight XAML that works: <telerik:RadGridView Name="GridView" AutoGenerateColumns="False" ShowGroupPanel="False">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="UNID" Width="100" DataMemberBinding="{Binding UNID}"></telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="FirstName" Width="100" DataMemberBinding="{Binding FirstName}"></telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="LastName" Width="200" DataMemberBinding="{Binding LastName}"></telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView> Silverlight XAML that throws the exception: <telerik:RadGridView Name="GridView" AutoGenerateColumns="False" ShowGroupPanel="False">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="UNID" Width="100" DataMemberBinding="{Binding UNID}"></telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="FirstName" Width="100" DataMemberBinding="{Binding FirstName}"></telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="LastName" Width="200" DataMemberBinding="{Binding LastName}"></telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="ClientType" Width="100" DataMemberBinding="{Binding ClientType.Name}"></telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView> Silverlight Code Behind: private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
{
DevforceCodeFirst.Data.PersistanceManager man = new Data.PersistanceManager();
var query = man.Clients;
man.ExecuteQueryAsync(query, cli =>
{
if (!cli.HasError)
GridView.ItemsSource = cli.Results;
});
} The log file is showing: <entry id="41" timestamp="2012-01-04T14:09:26" username="Guest - 1" source="IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport">CompositionContext: '-IbDefault-' - Probed for any 'EntityServerQueryInterceptor' and found 'IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor'.</entry>
<entry id="42" timestamp="2012-01-04T14:09:26" username="Guest - 1" source="IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor:ExecuteQuery">Fetch ... value(IdeaBlade.EntityModel.EntityQueryProxy`1[DevforceCodeFirst.Data.Entities.BaseEntity]).OfType()</entry>
<entry id="43" timestamp="2012-01-04T14:09:26" username="Guest - 1" source="IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport">CompositionContext: '-IbDefault-' - Probed for non-default 'IDataSourceKeyResolver' and found no matching exports.</entry>
<entry id="44" timestamp="2012-01-04T14:09:26" username="Guest - 1" source="IdeaBlade.EntityModel.Edm.DbKey:Initialize">Initializing DbKey for DevforceCodeFirst, connectionString = ''</entry>
<entry id="45" timestamp="2012-01-04T14:09:26" username="Guest - 1" source="IdeaBlade.EntityModel.Edm.DbKey:FindSubTypedDbContext">DBKey 'DevforceCodeFirst': Found DbContext 'DevforceCodeFirst.Data.PersistanceManagerDbContext'</entry>
<entry id="46" timestamp="2012-01-04T14:09:26" username="Guest - 1" source="IdeaBlade.EntityModel.Edm.DbKey:FindModelAssembly">DataSourceKey: 'DevforceCodeFirst' found in assembly 'DevforceCodeFirst.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' at 4/01/2012 2:09:26 PM</entry>
<entry id="47" timestamp="2012-01-04T14:09:32" username="Guest - 1" source="IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport">CompositionContext: '-IbDefault-' - Probed for any 'IIdGenerator' and found 'IdeaBlade.EntityModel.StoreGeneratedIdGenerator'.</entry>
<entry id="48" timestamp="2012-01-04T14:09:32" username="Guest - 1" source="IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport">CompositionContext: '-IbDefault-' - Probed for non-default 'IConcurrencyStrategy' and found no matching exports.</entry>
<entry id="49" timestamp="2012-01-04T14:09:32" username="Guest - 1" source="IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport">CompositionContext: '-IbDefault-' - Probed for default 'IConcurrencyStrategy' and found 'IdeaBlade.EntityModel.DefaultConcurrencyValueSetter'.</entry>
<entry id="50" timestamp="2012-01-04T14:09:32" username="Guest - 1" source="IdeaBlade.EntityModel.Edm.ObjectQueryProcessor:WriteGeneratedSql">SELECT
'0X0X' AS [C1],
[Extent1].[UNID] AS [UNID],
[Extent1].[CreatedDate] AS [CreatedDate],
[Extent2].[FirstName] AS [FirstName],
[Extent2].[LastName] AS [LastName],
[Extent2].[BirthDate] AS [BirthDate],
[Extent2].[ClientTypeUNID] AS [ClientTypeUNID]
FROM [dbo].[BaseEntity] AS [Extent1]
INNER JOIN [dbo].[Client] AS [Extent2] ON [Extent1].[UNID] = [Extent2].[UNID]</entry>
<entry id="51" timestamp="2012-01-04T14:09:36" username="" source="IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport">CompositionContext: '-IbDefault-' - Probed for any 'ICompositionContextResolver' and found no matching exports.</entry>
<entry id="52" timestamp="2012-01-04T14:09:36" username="Guest - 2" source="IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport">CompositionContext: '-IbDefault-' - Probed for any 'EntityServerSaveInterceptor' and found 'IdeaBlade.EntityModel.Server.EntityServerSaveInterceptor'.</entry>
<entry id="53" timestamp="2012-01-04T14:09:37" username="Guest - 2" source="IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport">CompositionContext: '-IbDefault-' - Probed for non-default 'IVerifierProvider' and found no matching exports.</entry>
<entry id="54" timestamp="2012-01-04T14:09:37" username="Guest - 2" source="IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport">CompositionContext: '-IbDefault-' - Probed for any 'IEdmSaveExecutor' and found 'IdeaBlade.EntityModel.Edm.EdmSaveExecutor'.</entry>
<entry id="55" timestamp="2012-01-04T14:09:43" username="Guest - 2" source="IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor:ExecuteQuery">Fetch ... value(IdeaBlade.EntityModel.EntityQueryProxy`1[DevforceCodeFirst.Data.Entities.BaseEntity]).OfType()</entry>
<entry id="56" timestamp="2012-01-04T14:09:43" username="Guest - 2" source="IdeaBlade.EntityModel.Edm.ObjectQueryProcessor:WriteGeneratedSql">SELECT
'0X0X' AS [C1],
[Extent1].[UNID] AS [UNID],
[Extent1].[CreatedDate] AS [CreatedDate],
[Extent2].[FirstName] AS [FirstName],
[Extent2].[LastName] AS [LastName],
[Extent2].[BirthDate] AS [BirthDate],
[Extent2].[ClientTypeUNID] AS [ClientTypeUNID]
FROM [dbo].[BaseEntity] AS [Extent1]
INNER JOIN [dbo].[Client] AS [Extent2] ON [Extent1].[UNID] = [Extent2].[UNID]</entry>
<entry id="57" timestamp="2012-01-04T14:09:43" username="Guest - 2" source="IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor:ExecuteQuery">Fetch ... value(IdeaBlade.EntityModel.EntityQueryProxy`1[DevforceCodeFirst.Data.Entities.ClientType]).Where(t => (t.UNID == "clienttype1"))</entry>
<entry id="58" timestamp="2012-01-04T14:09:43" username="Guest - 2" source="IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport">CompositionContext: '-IbDefault-' - Probed for any 'EntityServerErrorInterceptor' and found 'IdeaBlade.EntityModel.Server.EntityServerErrorInterceptor'.</entry>
<entry id="59" timestamp="2012-01-04T14:09:43" username="Guest - 2" source="IdeaBlade.EntityModel.Server.EntityServerErrorInterceptor:OnError">Caught exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: There are no EntitySets defined for the specified entity type 'DevforceCodeFirst.Data.Entities.ClientType'. If 'DevforceCodeFirst.Data.Entities.ClientType' is a derived type, use the base type instead.
Parameter name: TEntity
at System.Data.Objects.ObjectContext.GetEntitySetForType(Type entityCLRType, String exceptionParameterName)
at System.Data.Objects.ObjectContext.CreateObjectSet[TEntity]()
--- End of inner exception stack trace ---
at IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor.HandleException(Exception e, PersistenceFailure failureType)
at IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor.OnExecuteQuery()
at IdeaBlade.EntityModel.Server.EntityServerQueryInterceptor.Execute(IEntityQuery entityQuery, SessionBundle sessionBundle, IEntityServer entityServer)
at IdeaBlade.EntityModel.Server.EntityServer.Fetch(SessionBundle sessionBundle, IEntityQuerySurrogate surrogate)
at SyncInvokeFetch(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</entry>
I have a simple code first model (see below): [ProvideEntityAspect]
[Table("BaseEntity")]
public partial class BaseEntity
{
[Key]
[Column("UNID")]
public string UNID { get; set; }
[Column("CreatedDate")]
public DateTime CreatedDate { get; set; }
} [Table("Client")]
public class Client : BaseEntity
{
[Column("FirstName")]
public string FirstName { get; set; }
[Column("LastName")]
public string LastName { get; set; }
[Column("BirthDate")]
public DateTime BirthDate { get; set; }
[Column("ClientTypeUNID")]
[ForeignKey("ClientType")]
public string ClientTypeUNID { get; set; }
public ClientType ClientType { get; set; }
} [Table("ClientType")]
public class ClientType : BaseEntity
{
[Column("Name")]
public string Name { get; set; }
}
I have created a custom manager class: public class PersistanceManager : EntityManager
{
#region Constructors
public PersistanceManager(
bool shouldConnect = true,
string dataSourceExtension = null,
EntityServiceOption entityServiceOption = EntityServiceOption.UseDefaultService,
string compositionContextName = null)
: base(shouldConnect, dataSourceExtension, entityServiceOption, compositionContextName) { }
public PersistanceManager(EntityManagerContext entityManagerContext)
: base(entityManagerContext) { }
public PersistanceManager(
EntityManager entityManager,
bool shouldConnect,
string dataSourceExtension = null,
EntityServiceOption entityServiceOption = EntityServiceOption.UseDefaultService,
string compositionContextName = null)
: base(entityManager, shouldConnect, dataSourceExtension, entityServiceOption, compositionContextName) { }
public PersistanceManager(EntityManager entityManager, EntityManagerContext entityManagerContext = null)
: base(entityManager, entityManagerContext) { }
#endregion Constructors
public EntityQuery<Entities.BaseEntity> BaseEntities { get; set; }
public EntityQuery<Entities.Client> Clients
{
get
{
return BaseEntities.OfType<Entities.Client>();
}
}
public EntityQuery<Entities.ClientType> ClientTypes
{
get
{
return BaseEntities.OfType<Entities.ClientType>();
}
}
}
and I have created also created a custom dbcontext class: [DataSourceKeyName("DevforceCodeFirst")]
class PersistanceManagerDbContext : DbContext
{
static PersistanceManagerDbContext()
{
ConfigureForSqlServer();
}
private static void ConfigureForSqlServer()
{
//TODO: this should be changed so its just a hardcoded default, first choice should always be in the web/app config settings, but we can do that later.
// I think we will have to write code that goes and opens a config file relative to this assembly, as being a static method that is invoked internally, we cannot reference any application scoped variables or config.
// Set base connection string
const string baseConnectionString =
"Data Source=localhost; " +
"Integrated Security=True; " +
"MultipleActiveResultSets=True; " +
"Application Name=Prisms7Server";
Database.DefaultConnectionFactory = new SqlConnectionFactory(baseConnectionString);
}
public PersistanceManagerDbContext(string connection = null) : base(connection)
{
// Do not use in production; for early development only
Database.SetInitializer(
new DropCreateDatabaseIfModelChanges<PersistanceManagerDbContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Ignore<EntityAspect>(); // Always ignore EntityAspect
}
public DbSet<Entities.BaseEntity> BaseEntities { get; set; }
public DbSet<Entities.Client> Clients { get; set; }
public DbSet<Entities.ClientType> ClientTypes { get; set; }
}
|