- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
DuplicateNameException from DataSet
Joined: 03-Sep-2007
The CustomerEntity has two subclasses: NatureCustomerEntity and CompanyCustomerEntity. It a Target-per-entity hierarchy between these types.
I met a DuplicateNameException from the DataSet: "The DataTable has already had CustomerId column" when I was projecting any of the three types (for example EntityCollection<CustomerEntity>) to a DataSet.
If there's no any record for NatureCustomerEntity and CompanyCustomerEntity in database tables, I'll get the DataSet successfully.
EntityCollection<CustomerEntity> customers = new EntityCollection<CustomerEntity>(new CustomerEntityFactory());
using (DataAccessAdapter adapter = new DataAccessAdapter())
{
adapter.FetchEntityCollection(customers, null);
}
DataSet result = new DataSet("Customers");
customers.CreateHierarchicalProjection(result);
Joined: 03-Sep-2007
The version of SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll is "2.5.7.907".
Stack trace:
At System.Data.DataColumnCollection.RegisterColumnName(String name, DataColumn column, DataTable table)
At System.Data.DataColumnCollection.BaseAdd(DataColumn column)
At System.Data.DataColumnCollection.AddAt(Int32 index, DataColumn column)
At System.Data.DataColumnCollection.Add(DataColumn column)
At SD.LLBLGen.Pro.ORMSupportClasses.DataProjectorToDataTable.CreateColumns(IList projectors, Object[] rawProjectionResult)
At SD.LLBLGen.Pro.ORMSupportClasses.DataProjectorToDataTable.AddProjectionResultToContainer(IList projectors, Object[] rawProjectionResult)
At SD.LLBLGen.Pro.ORMSupportClasses.DataProjectorToDataTable.SD.LLBLGen.Pro. ORMSupportClasses.IEntityDataProjector.AddProjectionResultToContainer(List`1 propertyProjectors, Object[] rawProjectionResult)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityViewBase`1.CreateProjection(List`1 propertyProjectors, Boolean allowDuplicates, IPredicate filter, IEntityDataProjector projector)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityView2`1.CreateProjection(List`1 propertyProjectors, DataTable destination, Boolean allowDuplicates, IPredicate filter)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityView2`1.SD.LLBLGen.Pro.ORMSupportClasses.IEntityView2.CreateProjection(List`1 propertyProjectors, DataTable destination, Boolean allowDuplicates, IPredicate filter)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.CreateHierarchicalProjectionInternal(List`1 collectionProjections, DataSet destination, Dictionary`2 entitiesPerType)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.CreateHierarchicalProjection(DataSet destination)
At OrderEntryClient.Form1.ProjectDataSet() At C:\\work\\LLBLGen Pro\\OrderEntryClient\\OrderEntryClient\\Form1.cs: line 273"
Joined: 03-Sep-2007
Thanks a lot.
The new build has answered my first question, but my real problem was that CompanyEntity is just a relation entitiy of another OrderEntity. I didn't fetch it(CompanyEntity) alone but in prefetch paths for OrderEntity collection.
EntityCollection<OrderEntity> orders = new EntityCollection<OrderEntity>(new OrderEntityFactory());
RelationPredicateBucket filter = new RelationPredicateBucket();
filter.PredicateExpression.Add(new FieldCompareValuePredicate(OrderFields.CustomerId, null, ComparisonOperator.LessEqual, 3));
IPrefetchPath2 ppath = new PrefetchPath2(EntityType.OrderEntity);
ppath.Add(OrderEntity.PrefetchPathCustomer, new CustomerEntityFactory());
ppath.Add(OrderEntity.PrefetchPathOrderItem).SubPath.Add(OrderItemEntity.PrefetchPathProduct);
using (DataAccessAdapter adapter = new DataAccessAdapter())
{
adapter.FetchEntityCollection(orders, filter, ppath);
}
DataSet result = new DataSet("Orders");
There were two DataTables: NatureCustomerEntity and CompanyCustomerEntity in DataSet result for CustomerEntity, and I also lost the relation between OrderEntity and CompanyEntity in DataSet. That's not what I want. Although I've understood that Prefetch Paths support polymorphic access. But accessing just the super classes but not the sub classes is more often in my case. So, I have to do some extra work like below. Is there another way to do it more sensible?
DataTable dt = new DataTable("CustomerEntity");
dt.Merge(result.Tables["NatureCustomerEntity"]);
dt.Merge(result.Tables["CompanyCustomerEntity"]);
result.Tables.Add(dt);
result.Relations.Add(new DataRelation("OrderEntity_Customer", result.Tables["CustomerEntity"].Columns["CustomerId"], result.Tables["OrderEntity"].Columns["CustomerId"]));
Sorry. I have another problem pertained to this title Projetion. The scenario is that TransitionEntity has two related ActivityEntity: FromActivity and ToActivity. Method CreateHierarchicalProjection() issued an ArgumentException: "These columns have duplicated value".
EntityCollection<TransitionEntity> transitions = new EntityCollection<TransitionEntity>(new TransitionEntityFactory());
RelationPredicateBucket filter = new RelationPredicateBucket();
filter.PredicateExpression.Add(new FieldCompareValuePredicate(TransitionFields.ProcId, null, ComparisonOperator.Equal, 10000));
IPrefetchPath2 ppath = new PrefetchPath2(EntityType.TransitionEntity);
ppath.Add(TransitionEntity.PrefetchPathFromActivity);
ppath.Add(TransitionEntity.PrefetchPathToActivity);
using (DataAccessAdapter daa = new DataAccessAdapter())
{
daa.FetchEntityCollection(transitions, filter, ppath);
}
DataSet ds = new DataSet();
transitions.CreateHierarchicalProjection(ds);
Here's its StackTrace.
At System.Data.ConstraintCollection.AddUniqueConstraint(UniqueConstraint constraint)
At System.Data.ConstraintCollection.Add(Constraint constraint, Boolean addUniqueWhenAddingForeign)
At System.Data.DataTable.set_PrimaryKey(DataColumn[] value)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.CreateHierarchicalProjectionInternal(List`1 collectionProjections, DataSet destination, Dictionary`2 entitiesPerType)
At SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.CreateHierarchicalProjection(DataSet destination)
Here's the runtime library version: SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll is "2.5.7.1017" SD.LLBLGen.Pro.ORMSupportClasses.NET11.dll is "2.5.7.907"
jason... wrote:
Thanks a lot.
The new build has answered my first question, but my real problem was that CompanyEntity is just a relation entitiy of another OrderEntity. I didn't fetch it(CompanyEntity) alone but in prefetch paths for OrderEntity collection.
EntityCollection<OrderEntity> orders = new EntityCollection<OrderEntity>(new OrderEntityFactory()); RelationPredicateBucket filter = new RelationPredicateBucket(); filter.PredicateExpression.Add(new FieldCompareValuePredicate(OrderFields.CustomerId, null, ComparisonOperator.LessEqual, 3)); IPrefetchPath2 ppath = new PrefetchPath2(EntityType.OrderEntity); ppath.Add(OrderEntity.PrefetchPathCustomer, new CustomerEntityFactory()); ppath.Add(OrderEntity.PrefetchPathOrderItem).SubPath.Add(OrderItemEntity.PrefetchPathProduct); using (DataAccessAdapter adapter = new DataAccessAdapter()) { adapter.FetchEntityCollection(orders, filter, ppath); } DataSet result = new DataSet("Orders");
There were two DataTables: NatureCustomerEntity and CompanyCustomerEntity in DataSet result for CustomerEntity, and I also lost the relation between OrderEntity and CompanyEntity in DataSet. That's not what I want. Although I've understood that Prefetch Paths support polymorphic access. But accessing just the super classes but not the sub classes is more often in my case. So, I have to do some extra work like below. Is there another way to do it more sensible?
DataTable dt = new DataTable("CustomerEntity"); dt.Merge(result.Tables["NatureCustomerEntity"]); dt.Merge(result.Tables["CompanyCustomerEntity"]); result.Tables.Add(dt); result.Relations.Add(new DataRelation("OrderEntity_Customer", result.Tables["CustomerEntity"].Columns["CustomerId"], result.Tables["OrderEntity"].Columns["CustomerId"]));
Hierarchical projections are per type, so as the projection engine detects the different subtypes it creates per type a datatable, that's how hierarchical projections work.
I didn't completely understand your goal in this case. What you do is fetch orders and customers. You have subtypes defined for customer, so you get 3 datatables: Order, NatureCustomer and CompanyCustomer, and instead of having relations between order and these 2 customer datatables, you don't get the relations? Or is it that you DO get these relations but you want to get just 2 datatables? In the case of the latter, that isn't supported.
Sorry. I have another problem pertained to this title Projetion. The scenario is that TransitionEntity has two related ActivityEntity: FromActivity and ToActivity. Method CreateHierarchicalProjection() issued an ArgumentException: "These columns have duplicated value".
EntityCollection<TransitionEntity> transitions = new EntityCollection<TransitionEntity>(new TransitionEntityFactory()); RelationPredicateBucket filter = new RelationPredicateBucket(); filter.PredicateExpression.Add(new FieldCompareValuePredicate(TransitionFields.ProcId, null, ComparisonOperator.Equal, 10000)); IPrefetchPath2 ppath = new PrefetchPath2(EntityType.TransitionEntity); ppath.Add(TransitionEntity.PrefetchPathFromActivity); ppath.Add(TransitionEntity.PrefetchPathToActivity); using (DataAccessAdapter daa = new DataAccessAdapter()) { daa.FetchEntityCollection(transitions, filter, ppath); } DataSet ds = new DataSet(); transitions.CreateHierarchicalProjection(ds);
Here's its StackTrace.
At System.Data.ConstraintCollection.AddUniqueConstraint(UniqueConstraint constraint) At System.Data.ConstraintCollection.Add(Constraint constraint, Boolean addUniqueWhenAddingForeign) At System.Data.DataTable.set_PrimaryKey(DataColumn[] value) At SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.CreateHierarchicalProjectionInternal(List`1 collectionProjections, DataSet destination, Dictionary`2 entitiesPerType) At SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.CreateHierarchicalProjection(DataSet destination)
Here's the runtime library version: SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll is "2.5.7.1017" SD.LLBLGen.Pro.ORMSupportClasses.NET11.dll is "2.5.7.907"
If you fetch the graph with a Context, the FromActivity and ToActivity entity are the same entity OBJECT. Now they're two separate objects. So they're seen as two instances, and added as such, even though the entity (data) is the same.
Could you try that for me please?
Joined: 03-Sep-2007
I didn't completely understand your goal in this case. What you do is fetch orders and customers. You have subtypes defined for customer, so you get 3 datatables: Order, NatureCustomer and CompanyCustomer, and instead of having relations between order and these 2 customer datatables, you don't get the relations? Or is it that you DO get these relations but you want to get just 2 datatables? In the case of the latter, that isn't supported.
For this question, I want to get just 2 datatables. So, forget it. Thanks anyway.
If you fetch the graph with a Context, the FromActivity and ToActivity entity are the same entity OBJECT. Now they're two separate objects. So they're seen as two instances, and added as such, even though the entity (data) is the same.
Could you try that for me please?
I don't quite know how to fetch the graph with a Context by FetchEntityCollection() method. Could you give me a hint for that?
To fetch a graph with a context using fetch entity collection, you first add the collection to the context, and then fetch the collection.
It's not passing the context to the method, as it would require alot of overloads, plus the context is actually for the entities inside the collection.
so: Context c = new Context(); c.Add(myCollection); adapter.FetchEntityCollection(myCollection, filter, ... );