I'm starting to use Master Data Services and I came across something strange. When I deploy the sample models and entities and afterwards go to the Master Data Manager website, I see under "System Administration" in the left column under the Model name a tree structure of entities.
However, when I created my own model and entity (+attributes), I couldn't find the entity under the model on the left side.
How can I fix this?
I suppose that is also why I get an "invalid entity" error message when trying to create members through the API.
I was able to fix this, although I'm not sure if it's really necessary to 'fix'.
When creating an entity, if you set "enable explicit hierarchies and collections" to "yes", the entity will be placed in the left-hand side tree view too.
I'm not sure if it's absolutely necessary to do so for at least one entity but it did help in my case.
Microsoft mentions the following about this ( http://technet.microsoft.com/en-us/library/ff487054.aspx ):
From the Enable explicit hierarchies and collections list, select one of the following options:
No. Select this option if you do not need to enable the entity for explicit hierarchies and collections. You can change this later if needed.
Yes. Select this option when you want to enable the entity for explicit hierarchies and collections. In the Explicit hierarchy name box, type a name. Optionally, select Mandatory hierarchy (all leaf members are included to make the explicit hierarchy a mandatory hierarchy.
Hope this helps.
The "strange" view is the Model View, and the entities you add from the left to the right side will be displayed in the "Explorer" view (inside the Explorer function, there is an Explorer menu as well).
Related
PowerAMC/PowerDesigner allows you to create "graphical synonyms" of underlying entities allowing you to place the same entity twice (or more) on a diagram. Each is an instance of the same entity. This is great to pretty-up diagrams when, somehow, an entity must be linked to two others that happen to be on opposite ends of the diagram.
Is there a way to do this in Visio 2010 when using the database modeling template?
There are two ways of doing this:
Open the Table and Views panel (Database tab, Model Preferences, first tab, "when deleting an object from the diagram" should be on "Ask the user")
Drag and drop the existing table from that panel onto the diagram
This creates a duplicate of the logical entity and recreates all links (relations) to it. Not immediately useful to clean up the diagram but if you delete the extraneous links and say "No" when it asks if it should also delete the logical elements, then the links disappear visually but the foreign keys remain.
Second method:
Copy a table from the diagram (CTRL+C)
In the Home tab, choose to Paste, Special Paste and keep what should be the default mode: Visio diagram data
A copy of the table will appear but it won't be automatically linked to anything visually.
From both points, the duplicates on the diagram are both logically the same entity. This means that if you modify one, the other is also modified. If you link one to something, the other one is also logically linked (foreign keys will be listed in both, though only one may have the visual link).
Note: I'm using the French version of Visio so exact labels mentioned may be different in English. I tried translating to the best of my ability.
If you press the control key then click and drag an entity it will create a synonym.
I have yet to figure out how to remove a specific synonym without deleting all replicas of it.
I'm using ASP.NET MVC3 with Entity Framework 4.
I am using the Unit Of Work + Generic Repository pattern.
I searched for similar question everywhere, I see that many people have my problem, but still can't find a good and practical solution.
We have a multi-tenant database.
Imagine a database with a similar structure:
customers
groups, associated to a customer
users, associated to one or many groups
And then, for each customer we have
resources, associated to one or many groups, and linked between each other with foreign keys, many-to-many relationships and so on
So, when a user logs in, he is associated to one or many groups, and he needs to have access to the parent and child resources associated to that groups.
Now the problem is:
I implemented a sort of pre-filtering with a .Where() clause into the unit of work, in the repositories, based on the id of the logged in user.
And this is working.
The pre-filtering I did on the repositories is working fine, but of course it works only if you access directly the repository of the sources of TYPE A or TYPE B or TYPE C and so on.
But a resource is linked to other resources with many-to-many tables and foreign keys.
So, it happens that sometimes a resource belongs to a group to which the user has access, but sometimes the resources linked to this resource belong to a group to which the user does not have access.
If I traverse the navigation properties of the "parent" resource, the user can access all the linked resources, even the one belonging to other groups.
So, if you are starting from a TYPE A resource, and traverse the navigation properties to reach the TYPE B and TYPE C resources, they are not filtered.
If you access the TYPE B and TYPE C repositories, they are filtered.
Now my filters, as I said before, are in the Unit Of Work class, but I tried to move them into a custom DBContext, applying the filters directly into the DBSet, but nothing changes:
It seems that EF is accessing directly the database to build the navigation properties, thus not using the other repositories or the other DBSet, avoiding the prefilter.
What can we do?
I see that NHibernate has Global Filters that could accomplish my task, so I'm evaluating a migration from EF to NH.
I see that many other people is asking for .Include() filters, thus disabling lazy loading.
Thank you.
I can provide some piece of code if needed, but I hope I explained my problem correctly.
Thank you i.a.
Best Regards,
Marco
I saw a solution with mapping to views and stored procedures, but I'm not sure how hard it was in development and maintanace. In short, it is possible to map EF model to views, where data will be filtered; in this solution each user have own database credentials.
I have an Entity called "Product", this entity, through table mapping, merges 6 tables that have a 1 to 1..0 relationship with "Products". This all works wonderfully. There is another property I want to add to "Products", which is sBBR_rate, this value is not in a table that has a direct 1 to 1..0 relationship, it is related through a link table as below:
When I import the two tables into the EDM, I can't see a way in the "Mapping Details" of
"Product" to reference the sBBR_rate. I can reference RatesLink and link that to the "Products" primary key, however, I cannot reference the BBR table.
The methods I can think of to work "around" this is are as follows:
Create a view, reference the view in the EDM.
Create an SP and use a function import to retrieve the BBR when it is required.
Create a "Rates" entity in the EDM that can then draw down the sBBR_rate into it. Navigate to the Products BBR through Product.Rates.sBBR_rate.
Is there a better way I can do this that doesn't feel so much like a fudge? Perhaps by directly editing the XML of the Mapping or Conceptual layers of the EDM?
Thanks for your input.
Because the multiplicities on the Product -> RatesLink and RatesLink -> BBR relationships are 0 to 1, you should be able to access the sBBR_rate from a Product instance like this:
myProductInstance.RatesLink.BBR.sBBR_rate
I can see on the EDM screenshot that RatesLink has a Product and BBR property, which would indicate this should be available - is it?
On a side note, if it makes sense for the sBBR_rate property to commonly be accessed directly from Product, you might want to follow the law of demeter and create a property on Product which returns it directly.
The model we are using is to extend entities by using partial classes which we've found useful so we can get additional properties in the autogenerated classes (we are using a POCO T4 template to autogen but I believe this would work just as well with the default entity object generation).
So we would have
//.. this one is from the T4 template
public partial class Product
{
//.. all the autogenerated methods
}
and in a separate file that isn't autogened
//.. now in a separate file created by me
public partial class Product
{
//.. my custom properties and methods to make the entities more usable
public string BBRRate
{
get {return this.RatesLink.BBR.sBBR_rate; }
}
}
This means that I can just do
myProduct.BBRRte
I know there are other ways to do this by amending the edmx file but this one we found easy to implement. You just need to watch performance because you are potentially loading extra data. Also we did this with LazyLoading turned on but with more work you wouldn't have to
We also experimented with hooking into the ObjectMaterialized event in the ObjectContext class to preload some of these properties. Using a custom interface i.e. IMaterialisable we could check if the object was of that type then call a method (Materialise) to prepopulate some of the properties. This seems like a good idea but we didn't widely use it - it was easy to load up too much stuff. If you do the load on the properties in the partial classes then it becomes more efficient. Just my experience.
Anyway - as always an interesting question and good luck again with your dev.
EDIT
There is a rule that everything in the store layer must be represented some way in your conceptual layer. Therefore removing the tables from the conceptual layer but bring through some of the properties I don't think will work in it's gross form. Therefore I can think of two further options
Create a View on the database and bring that in as you have already mentioned. TBH this is what I would do.
Use the DefiningQuery element directly in your xml (the store layer) and map the query through to a custom entity of your exact design. Julie Lerman describes this as the ultimate escape hatch for Entity Framework.
Remember though - if you manual amend the XML in point 2 then you lose the ability to automatically update the module through the IDE
I ended up creating a view and then linking this view in the EDM, this worked a treat.
I'm trying to get a presentation model (discussed here and here) working in RIA. All the examples I can find are simple, flat data entities with no 1-many or many-many relationships, which are what I can't get working - specifically, on updates and inserts into associative relationships.
Queries I can get working fine - I have my presentation classes marked up with Association attributes (and Include attributes, where appropriate), and I have a good understanding about how data is loaded into the client side and maintained there as entities. I also have inserts of new entities covered. However, I'm experiencing the following problems. For the following examples, assume we have simple Album and Artist entities, where an Album has a single artist and an Artist can have zero to many albums. Both have a Name property.
On the client side, if I do myArtist.Albums.Add(anAlbum) or myArtist.Albums.Remove(anAlbum), nothing happens. HasChanges returns false. (Note that myArtist and anAlbum were obtained solely in code by loading the entities and iterating to get references to specific entities: I'm not doing anything in UI or with DomainDataSources yet, just dinking around).
If I update the Name on an Artist and SubmitChanges, when the Update method gets called on the server, the Albums collection is null.
Does anyone have any suggestions, or can you point me to an example that uses more complex objects?
EDIT (keeping the above for posterity): Alright, it appears that the second issue (a reference to an entity or a collection of entities showing as null when Update gets called on the server) exists because the child entites aren't marked as Changed and so they aren't being serialized and sent back. I know you can force that to happen by using [Composition] and I have gotten it to work that way, but this is not a compositional relationship and I want both entities to be "top-level" entities. How can I mark an entity as changed?
The problem was that my [Association] attributes weren't correctly defined. I didn't realize that the association's Name property has to be the same on both sides of the association. When the names are the same and you do a build, the generated code on the client uses a different constructor for the EntityCollection used by the "parent" to refer to the "children" than it does if the associations aren't set up right. The new constructor takes callbacks that do a little bit of extra handling when you call Add and Remove on the collection - specifically, they take the child entity you are adding or removing and modify the property on it that refers to its parent so that everything remains in sync: the collection you removed the object from, the collection you added it to, and the object's reference to its parent.
I have objects:
type A (Id, Name),
type B (AId, Description).
I want to make relation 1-to-1 (and create it 1-to-[0..1]). All works great exept deleting objects of type A. When I'm trying to delete some object from type A exception occurs.
A relationship is being added or deleted from an AssociationSet ‘...’. With cardinality constraints, a corresponding ‘...’ must also be added or deleted.
Im searched for solution (found editing CSDL for many-to-many), but nothing helps. There is also cascade action defined in the table in Database.
Any suggestions?
UPD: Thanks for answers.
Let's say more clear.
I don't want to implement inheretance betwen A and B
I try to fix problem by editing edmx file (like this http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/), but no luck. Seems it's only worked for one-to-many.
I just want to have 2 objects with one-to-one relation. For example, Order and OrderDetails. I expected automatic creating/deleting OrderDetails for every Order I have.
1:1 should give an exception if your deleting B right?
I think what you want is 0..1
Right click Add->associations.
under multiplicity:
On the left hand side choose One for A and 0 or 1 on the right for B.
I think you need this if you want an optional description object(B) for A.
You could also move B's fields into A and check not null for those fields right? That might be easier, then I think you could just use A's fields.
Also, I'm not a database designer by a long shot but, wouldn't you want the Data of A in A?
If for instance you had "Person" and his "Home", I would think those would be a good case for 1:1 (or 0..1 real world), because they themselves are 2 distinct objects that other objects can share independently.
Seems like the A_DataObjects just leads to an unnecessary join?
Old Answer below (not looking for inheritance, but leaving for someone else):
OK, I think I ran into this today. I think what you might want to do is define 2 classes as subclasses of a base class (entity). Right click and do add -> inheritance to get started. I didn't get this all working yet, but I think it involves specifying a field in the base, BaseType which can be used to key in on the derived classes.
http://mosesofegypt.net/post/Inheritance-and-Associations-with-Entity-Framework-Part-1.aspx
Note, there's a part 2 and 3 of this.
-David
One way to do this is to have a single entity that maps to 2 tables. See:
http://msdn.microsoft.com/en-us/library/bb896233.aspx
Visual EntityFramework tool doesn't recognize correctly 'on delete cascade' and creates incomplete xml mapping. You have to change edmx file (You can do it with notepad). Instructions here:
http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/
Worked for me.
Just make a one-to-many relationship, then by creating unique constraints on the foreign keys in the database you can force it to be 1:1. You can find a full tutorial about it here
(This uses Code-First)