有时间再翻译吧
This can be very confusing and aggravating, and this is a scenario I've walked through with several clients. Why does this happen? And what should be a proper approach for upgrading a Feature that includes Site Columns or Content Types?
Site Columns and Content Types in List
When you add a Content Type, or a Site Column, to a list, SharePoint actually makes a copy of that item in the list. However, the copy seems to retain the same GUID/Identifier as the original item. This allows several things:
Deactivating Your Feature
What happens when you deactivate your feature? Typically, if a Site Column or Content Type is not being referenced in any list or anywhere else in the site, SharePoint will remove it from the Site Collection. However, if it's being used, SharePoint will often delete the ones that aren't be used, but leave the ones that are. On occasion, deactivating the Site Columns will actually remove the items. However, the copies of the assets will remain in the underlying lists. This might seem confusing at first, but it's because the lists contain copies. (Using our analogy again, if siblings' parents go on vacation, the siblings still retain their last name and their sibling relationship, whether the parents are around or not.)
I'd like to add a little caveat here: I have run into many issues with SharePoint when it comes to modifying Site Columns and Content Types using Features, whether it means changing the Site Column type, changing the composition of Content Types, etc. Because SharePoint is keeping track of multiple versions of these assets, you can easily get it confused, especially if you try to change the very field type of a Site Column. The purpose of this blog entry is to make this easier for you. However, I strongly recommend you have a clean development environment to work on, since once you run into a mismatch in show SharePoint handles its Site Columns or Content Types, it has the possibility of disrupting operations for your whole Site Collection.
Activating Your Feature
If we think about it in reverse, what happens when we activate a feature? SharePoint uses the CAML markup we used to define our Site Column or Content Type, and it puts it into the database. This is a one-type event. What do I mean by that? If you create a Master Page via a Feature, you do put a reference to that Master Page in SharePoint, so that you get your new Master Page showing up in the Master Page Gallery for your site. However, all that reference does is point to the file system. Any time SharePoint to use that Master Page, it says, "Hmm, looks like I should look at the file on the file system in the Features folder instead of a file stored in my database." However, with Content Types, once the Feature has been activated, SharePoint uses the CAML to add the Site Column or Content Type to its database, and it never uses that asset on the file system again. Basically, it's the same as using a Feature Receiver that executes code once when the Feature is activated, and never again. (Please note: I have no inside information from Microsoft about this! This is just what I've inferred based on the behavior of these assets.)
Creating Site Columns and Content Types Using a Feature Receiver
So this begs the question, why not just use a Feature Receiver that executes code which instantiates these things into SharePoint, and just forget the CAML markup altogether? Well, remember what we were saying about the relationship between GUIDs in the lists and their parent items in the Site Collection? It's often important that if you're activating and deactivating a Feature in a Site Collection that the GUIDs remain the same, so-as to prevent orphaning those assets in the child lists. Furthermore, if you're activating the Feature in multiple Site Collections, you probably want continuity between the assets in different Site Collections.
When you create a new Site Column via code, using the SiteColumnCollection.Add() method, SharePoint automatically creates a GUID for that Site Column. The only way you could hard-code that GUID would be to create the Site Column by passing in the entire XML definition. Well, if you're going to do that, you might as well just use the CAML way of doing things. And what about Content Types? I looked, and I don't even see a way of specifying the unique identifier for a Content Type. It's true, you can pass in the parent Content Type, and the way SharePoint constructs ID's for Content Types, its ID includes the ID of its parent. However, I have found of no way of passing in what the newly-created Content Types unique part of the ID should be. (If you're confused about what I'm talking about when referring to Content Type IDs, take a look here: http://msdn.microsoft.com/en-us/library/aa543822.aspx.)
Recommended Approach
Based on all these factors, my suggestion is this:
You have a choice when it comes to how you maintain the CAML and the Feature Receiver, since you have two scenarios: existing Site Collections and new ones.
Deleting Site Columns and Content Types
If you've noticed, I haven't written much about deleting Content Types and Site Columns. That's because deleting a Column could easily mean deleting the content stored in that Column. As we've already noted, deleting a Site Column won't delete the copies of that Site Column from lists in the site that use it. If you want to delete a Column from a list, you'll need to write code that will explicitly allow this, since it means you'll also lose any content that was stored in that column in the list. You'll have to explicitly set a property called AllowDeletion on the SPField object you're trying to delete.
In terms of deleting a Content Type from a site, the same thing goes, in terms of deleting a Content Type from the Site Collection root won't necessarily remove the copies of that Content Type in lists. Also, removing a Content Type from a List after the Content Type has been removed from the Site Collection won't necessarily remove the Columns from the list, if it now thinks those Columns are just part of its own definition, and not a Content Type's columns.
In my experience, this is where things can get hairy, since you're dealing with copies without parents, etc. It's imperative that you do things in the right order, and practice in a development environment before trying to execute this sort of scenario in production.
Conclusion
Dealing with the issue of updating Site Columns and Content Types in SharePoint can be a tricky issue when using Features, but hopefully this will provide you some guidance about how to carry this out in your own environment