PK GUID Save() Bug

Posts   
 
    
Sam avatar
Sam
User
Posts: 95
Joined: 30-Jun-2004
# Posted on: 11-Nov-2005 00:41:02   

Here is what I am trying to do:

MyEnity entity = new MyEntity(//GUID of Me); Debug.Assert(entity.Name == "Me") //passes which means the entity was correctly fetched; entity.Name = "NewName"; entity.Save()//throws error:

"The entity 'MyEntity' doesn't have a PK defined. The update query will therefore affect all entities in the table(s), not just this entity. Please define a Primary Key field in the designer for this entity."

However in the designer and database the PK is set (to a GUID).

Even stranger is that Delete() works! disappointed So if I replace Save() with Delete() the record is correctly deleted. This seems like a fairly major bug (unless I am missing something stupid). Any ideas of what I can do?

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 11-Nov-2005 02:30:50   

What type of db are you using? Have you tried removing the entity from the designer and adding it and then regenerating the project?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 11-Nov-2005 09:34:20   

Sam wrote:

Here is what I am trying to do:

MyEnity entity = new MyEntity(//GUID of Me); Debug.Assert(entity.Name == "Me") //passes which means the entity was correctly fetched; entity.Name = "NewName"; entity.Save()//throws error:

"The entity 'MyEntity' doesn't have a PK defined. The update query will therefore affect all entities in the table(s), not just this entity. Please define a Primary Key field in the designer for this entity."

However in the designer and database the PK is set (to a GUID).

Even stranger is that Delete() works! disappointed So if I replace Save() with Delete() the record is correctly deleted. This seems like a fairly major bug (unless I am missing something stupid). Any ideas of what I can do?

I have some unittests which use an entity with a PK of GUID, and which work fine, so I'd like you to check the EntityFieldFactory.cs file and go to the line where the PK field is created for that entity. The line should look like:

fieldToReturn = new EntityField("ProductId", typeof(System.Guid), "ProductEntity", false, TypeDefaultValue.GetDefaultValue(typeof(System.Guid)), @"dbo", "Product", "ProductID", false, (int)SqlDbType.UniqueIdentifier, 0, 0, 0, true, false, "", false, null, typeof(System.Guid), (int)fieldIndex);

where the true after 0, 0, 0 is the flag for PK/FK. (as you will notice from the intellisense tooltip)

Could you check that for me please?

my testcode:


[Test]
public void SaveUpdateProduct()
{
    ProductEntity p = EntityCreator.CreateNewProduct(1);
    p.TestRunId = _testRunID;
    Assert.IsTrue(p.Save());

    ProductEntity fetchedP = new ProductEntity(p.ProductId);
    Assert.AreEqual(EntityState.Fetched, fetchedP.Fields.State);

    fetchedP.FullDescription += "lalala";
    Assert.IsTrue(fetchedP.Save());
}

ProductId is a guid.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 11-Nov-2005 11:39:55   

Could you please check if this is true: bool isPK = entity.Fields[(int)MyEntityFieldIndex.PK].IsPrimaryKey;

and: bool hasPK = (entity.Fields.PrimaryKeyFields.Count > 0);

THe exception you're seeing is thrown when the primary key filter creation routine returns null or an empty set of filters, which means no PK field was present and no filter could be created. So if the PK field is indeed not marked as a PK field something is wrong in the code being generated.

Frans Bouma | Lead developer LLBLGen Pro
Sam avatar
Sam
User
Posts: 95
Joined: 30-Jun-2004
# Posted on: 11-Nov-2005 20:40:24   

What type of db are you using? Have you tried removing the entity from the designer and adding it and then regenerating the project?

SQL Server 2000. I have not removed and re-added the entities (don't what to have to recreate all the derived entities again).

I have some unittests which use an entity with a PK of GUID, and which work fine, so I'd like you to check the EntityFieldFactory.cs file and go to the line where the PK field is created for that entity. The line should look like:


fieldToReturn = new EntityField("ProductId", typeof(System.Guid), "ProductEntity", false, TypeDefaultValue.GetDefaultValue(typeof(System.Guid)), @"dbo", "Product", "ProductID", false, (int)SqlDbType.UniqueIdentifier, 0, 0, 0, true, false, "", false, null, typeof(System.Guid), (int)fieldIndex); 

where the true after 0, 0, 0 is the flag for PK/FK. (as you will notice from the intellisense tooltip

Yes it is true

Could you please check if this is true: bool isPK = entity.Fields[(int)MyEntityFieldIndex.PK].IsPrimaryKey;

and: bool hasPK = (entity.Fields.PrimaryKeyFields.Count > 0);

bool isPK = entity.Fields[(int)MyEntityFieldIndex.PK].IsPrimaryKey; *//returns true* entity.Fields.PrimaryKeyFields.Count ; //returns 1

So it seems everything is correct. I didn't mention this; but this is a subclass entity. Although I have tried instantiating it as its super-class as well and got the same problem.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 12-Nov-2005 10:09:02   

Ok Subclass entity is another ballgame. I'll retry with a subclass. I assume it will be a TargetPerEntity subclass, is that correct?

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 12-Nov-2005 15:40:37   

Test with a subtype in a hierarchy of type: TargetPerEntity:


[Test]
public void SaveUpdateSpecialProduct()
{
    ProductEntity p = EntityCreator.CreateNewProduct(1);
    SpecialProductEntity sp = new SpecialProductEntity();
    sp.FullDescription = p.FullDescription;
    sp.ShortDescription = p.ShortDescription;
    sp.Price = p.Price;
    sp.ActionCode = 1;
    sp.ActionDate = DateTime.Now;
    sp.TestRunId = _testRunID;
    sp.SpTestRunId = _testRunID;
    sp.ProductId = p.ProductId;
    Assert.IsTrue(sp.Save());

    SpecialProductEntity fetchedSP = new SpecialProductEntity(sp.ProductId);
    Assert.AreEqual(EntityState.Fetched, fetchedSP.Fields.State);

    fetchedSP.FullDescription += "lalala";
    Assert.IsTrue(fetchedSP.Save());
}

works fine. Sp is updated normally.

Will now try in a hierarchy of targetPerEntityHierarchy.

(edit): bingo, the TargetPerEntityHierarchy doesn't work. Looking into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 12-Nov-2005 17:41:25   

Fixed in next build. Another bug was fixed as well, delete while using a root type also is fixed (failed in some occasions)

Frans Bouma | Lead developer LLBLGen Pro
Sam avatar
Sam
User
Posts: 95
Joined: 30-Jun-2004
# Posted on: 13-Nov-2005 23:18:22   

How should I go about resolving the issue? Do I have to wait for a new version? If so do you have a time frame?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 13-Nov-2005 23:58:13   

Sam wrote:

How should I go about resolving the issue? Do I have to wait for a new version? If so do you have a time frame?

Build is available, you should download the updated runtime library archive and use it in your solution. Please inform me if this didnt fix your problem. The easiest way to update is to place the updated runtime libs in the RuntimeLibraries folder in teh llblgen pro folder, overwriting the current version, tehn recompile.

Frans Bouma | Lead developer LLBLGen Pro
Sam avatar
Sam
User
Posts: 95
Joined: 30-Jun-2004
# Posted on: 14-Nov-2005 16:11:01   

smile That fixed it. Thanks!!!!!!