Avoiding "Unique field" conflicts in inheritance - c#-4.0

My situation
I have an entity model with a base class ItemBase which defines an ID, a name and a few other properties. The "ID" column is the identity, the "Name" colum is an unique field in the base table. This base class is also defined as an abstract class. So yes, it is a table in the database, but in EF4 I cannot create instances of this base class.
And I have five different entities that inherit from the base class. (Item1, Item2...Item5) So all of them inherit the properties of ItemBase and additional properties are stored in an alternate table. One table per type. Quite nice, actually!
My problem
An object of type Item2 could have the same name as an object of Item5. This would cause a problem since they would both end up with a record in the ItemBase table, and the Name field would be in conflict. That's just nasty. So if the Item2 class contains brands of television manufacturers and Item5 contains lists of smartphone manufacturers then "Samsung" cannot be added in both entity sets.
I need a solution that will work around this problem, while keeping it simple. (And without adding the Name field to all child tables, because YUCK!) Suggestions?
Way to solve this?
Because "Name" is in the base table and defined as 'Unique', I will end up with conflicts when two different entity classes have the same name. I need a solution where "Name" is in the base table, yet it's unique per child class only, not unique for the base class...
I could alter the child entities to add a prefix to the name when writing to the table, and removing it again when reading from the table. Or I add another field to the base table indicating the child class linked to it, and make "name"+"link" unique, instead of just "Name". Both solutions aren't very pretty and it's unclear to me how to implement one of those. So is there a better solution or else, how do I implement this nicely?

It cannot be solved by unique column. The unique key would need to be placed over two columns - one specifying the Name and one specifying the type of derived entity but that is not possible with the inheritance type you selected (Table-per-type) because EF will not create and maintain that additional column for you. That would be possible only with Table-per-hierarchy inheritance where all five child entities are stored in the same table as base class and there is discriminator column to differ among them.
To solve this with your current design you must either use trigger on base table with some query logic to find if name is unique per child or handle this completely in your application.

Related

How to drop duplicates in Workshop Object table

in a Workshop App, can duplicates (based on some specific columns) be eliminated from an Object Table? And how?
When I see a question like this, it is normally a hint that you may want a more expressive data model. For instance, if each object has a "category" property and you want to make a table of categories with a count of objects in each category you could:
a) Use a pivot table widget on the primary object
b) Create a new "category" object type linked to each object. Then make a regular object table and have a derived property counting the linked objects.
This can add some flexibility, though it has it's own limitations. You'll be able to easily go from categories -> linked objects, but if you have more the 100k objects and try to search around to the linked categories, you'll hit a limitation. So whether this approach works will depend on the semantics and scale of your data model.

How to add duplicate record in relation entity coredata

I have two entity
Box
Items
I want to add multiple items on same box object but when i try to add multiple(duplicate) items on same box object then its store unique object record.
Kindly help me to solve that issue.
A Core Data relationship is a set, not an array. One of the defining characteristics of a set is that it doesn't contain duplicate entries. So, you can't have the same object appear twice in the same relationship. It's hard to tell what that would even mean... A Box is related to an Item twice?
If you're trying to do this to indicate quantity (i.e. two of the same Item in a Box) you'll need a third entity type that stores the quantity and has a relationship to the Item. Probably something like
Box <---->> BoxItem <<----> ItemType
Here the ItemType replaces your Item, and BoxItem stores the quantity and relates to one Box and one ItemType. Any time you add one ItemType to a Box you create a BoxItem with a quantity of one. If you add another of the same type, increase the quantity.

Insert new data to a blank row in core data

I want to add data (string) to one of the blank row in core data (iOS). How do you do that?
e.g : I have an entity of STUDENTS and in that entity has 3 attributes : index, name, age. the 3 attributes are filled with data, let's say it has 10 row of data. But on index 9 the attribute of name has no data (blank space). How do you fill that blank space ?
I can't describe it clearly because I can't upload an image yet.
You shouldn't think of Core Data as a database with rows and columns. It is an Object Graph and Persistence framework. So you deal with Objects (like rows) and object properties (like columns). So once you have fetched or created some objects you set their properties.
If you haven't created NSManagedObject subclasses from your object model then you have to use the KVC accessors:
[student10 setValue:#"William" forKey:#"name"];
If you do create subclasses you can use Objective-C properties.
student10.name = #"William";
I recommend reading more about Core Data in the Apple Documentation to gain a proper understanding of the framework. They also have some tutorials I think.

Managing dates in Section Headers with Core Data

I have conceptual issue with using core data. My app lists events by title in the main tableview then navigates to a tableview which is unique to the event. Here it's supposed to display in the section headers of the tableview an event date, a list of dates that expand a range (requires calculation) or list of unique dates.
I have arranged this in the model with 3 entities. Event & Date have a one to one relationship. Date to Menu have a one to many relationship. Menu contains the data for events that have unique dates, Dates contains events that either have a start date or in some cases when it's a range an end date.
Ok if the above is clear my question is how do I do create a list of section headers unique to an event? Bear in mind that NSFetchedResultsController only provides the ability to return a section name from a managedObject. I think this is what's throwing me.
Do I fetch the data unique to the event then use FRC to create arrays to populate the section headers and live with the table not being managed? Or is there a smarter way?
I don't really understand your model but I think it looks something like this:
Event{
name:string
date<-->Date.event
}
Date{
event<-->Event.date
menus<-->>Menu.date
}
Menu{
date<<-->Date.menus
}
If this isn't correct, you might try editing the question with the data model in this format it can be better understood. (if you can't edit, just fold the format into a comment and I will add it. Alternatively, send it me in an email.)
I'm not clear on what data you want in your Event table section titles. Sections are intended to be groupings of managed objects based on some attribute of those objects. The canonical example would be Contact.app's contact list. The contacts are grouped based on alphabetical value of the first letter of the last name.
Once common mistake is to think of a section table as representing hierarchal objects with the section titles representing superior objects and the rows representing inferior e.g. yo have a model to simulate a file system so you have a Directory entity and a File entity. You try to set the section titles to the name of the Directory and the rows to the names of the related File entities. That would not work smoothly and would not really mesh with the interface grammar that the user has learned for section titles. Instead, you should have a hierarchy of tableviews with a table showing all Directory objects and then a second table view showing all the File objects related to the selected `Directory object.
So, if the section titles you want come from any object besides Event you are probably approaching the problem from the wrong angle.

Sharepoint: Integrity of lookup fields after a list import

I got a question about the behavior of lookup fields when importing data. I wonder how the lookup fields behave when the list they point to is being replaced/imported. To explain the issue, I will provide a quick example below:
As example, assume we have these two sharepoint lists:
Product Types
-------------
+ Type Name
+ Code Nr
+ etc
Products
--------
+ Product Name
+ Product Type (Lookup field to list "Product Types")
+ etc
In my scenario, the Products List contains production data on the production Sharepoint platform. It is filled with data by the business users.
However the Product Types list contains rather static data and is maintained by the developer.
Now after a development cycle, the developer wants to deploy his new webparts and his new data (product types list). The developer performs the following procedure:
On the dev machine: Export "product type" list using stsadm
On the production machine: Delete all items in the "product type" list
On the production machine: Import the "product type" list using stsadm
This means we basically replace the "product type" list on the production server while keeping the "product" list as it is.
Now the question:
Is this safe? Will the lookup references break under certain circumstances?
Any downside of this import/export procedure?
What happens if someone accesses a "product" during the import? Will the (now invalid) reference clear its own content (become a null value).
What happens if the schema of the "product type" list changes (new column)? Will this cause any troubles?
Thanks for all feedback and suggestions!
Update 1
The imported "product type" items have the same IDs as previously deleted ones.
Update 2
Started a bounty to get some more feedback/opinions.
We have had this exact same scenario before. This is a little tricky, depending upon how you will approach it.
1) Delete and Recreate Product Type list through UI
If you delete and recreate the lookup List(Product Type in your case) through UI, then you will lose the connections because the List's id GUID will change upon recreation. So do not go that route.
2) Delete and Recreate Product Type through a Feature
If you had created the Product Type list through a feature.xml file using the <ListInstance> element, then if you delete that list and then recreate it using the same feature (basically Id attribute of ListInstance remains the same, number of list items, i.e. the number of <Row> elements, may change), the association would be maintained. So if you were adding 5 more product types, then if you had created the list using a feature, you could just delete the list and provision the new one using the same feature with extra info for new items and everything would just work!
As a side note, this is the better approach because if you have to do the upgrade on a lot of servers, then rather than doing list export import via stsadm, feature deactivation and activation is a much more recommended solution. This is how we did it.
3)Deleting all list items from Product Type and adding new ones (list is never deleted)
If you are linking the lookup field (in Product List) to the ID field of the lookup list(Product Type), you have to remember that ID is auto-incrementing, so if you delete all items and then add new ones, then their ID's would be different. Say you had 5 items with ID's (ID field is not shown in UI while editing in Datasheet view) 1-5 in the list. If you delete them and add new items, their ID's would start from 6 and not 1 again. So if your lookup field had link to the item with ID 1 in it, then this method is not going to work because there is no item with ID 1 in the Product Type list anymore. So you might want to really try this out before going to production with this method.
4) Editing the list in place
If the list is not extraordinarily huge, and you only have to make this change to one or two instances, could you not just edit the list directly in the datasheet view on the prod server? When editing in datasheet view, do not delete the item, but just overwrite the values of its columns. And you can add more items if you want. This will make sure your ID's are valid.
I have mostly talked about adding new items to the list. Now if you were deleting existing items, then your lookup fields will be affected because assuming you linked the field by ID, the ID is not present anymore since the item has been deleted. Basically, any method you use, maintaining your ID's is critical.
Now regarding your doubts/questions:
I am not too sure about stsadm export import for a list (never done it myself), but stsadm can be tricky as some operations will work on certain scopes only. So you better try out your exact scenario on a dev env.
What happens during an import is tricky again depending on the exact timing. I am sure SP has its own concurrency mechanisms, but you cannot have a definitive answer as it might probably be different based on the stage of the import. If possible, recommended approach is to do the import during a planned downtime.
Regarding changing schema of the list, a change in the schema of a list will not affect the existing list instances (for the most part). If you do this through UI, I believe SP makes changes to the content DB directly. I am not certain how you intend to do this, but if you were to add a column to an existing list using a feature, the way to do this is during feature activation by adding a new content type to the list and adding your new column to this content type. This way you add the column but do not affect the existing list items.
Good luck...
There are two components to a particular lookup: the field, and the field value. The field value only contains the ID of the item(s) it refers to, and the display field. This information is meaningless without the field, which specifies what list to look at and what field to use as the display field.
The primary reason that a Lookup will break occurs on the field scope: either the list it referred to no longer exists, or the list does not contain the required field. These would generally happen if you deleted and recreated the list, but you aren't doing that. If you do break a lookup's list reference, then the only thing you can do is re-create the lookup, because you cannot configure the list reference for a lookup field once it is created.
The downside of your import/export procedure is that you lose the validity of all currently existing lookup values. A lookup maintains its integrity based on the ID of the item it references. So when the display field changes, it still refers to the same item. If you delete the item, then the lookup no longer references it, even if you create a new item that has the same value for the display field. So you would have to reassign all of the products to the new product types.
It should be noted that if you were to revert the deletion of that item, it would return to being on the lookup! The reference to that ID is kept until the actual lookup value is updated (such as by editing the Product).
All of your now invalid references will be null for purposes of interaction. You won't see anything on display forms, and you won't have the options when you try to update the product. When you do update the product, you update it to what you just set it to, which since you can't set the non-existent IDs, means that there are no more references to those IDs.
Any changes to the Product Type list's schema that do not affect the display field specified for the lookup will not have any effect on the lookup integrity. If you do change the display field in any fashion, and of course if you delete it, then it will break in the same fashion as with the list reference. However, you can set the display field, both in the UI and in the object model, so it is easy to fix this.

Resources