EntityFramework custom many to many without navigation property - c#

I want to do many-to-many relation between these objects:
class Flyer {
Guid Id;
virtual ICollection<Address> Stores;
}
And:
class Address {
Guid Id;
}
Of course these models are simplified.
And I do not want a navigation property to Flyer inside Address because Address is in relation with other objects too. It is possible?
Fluent API only

How are you identifying what the address belongs to if it can belong to multiple different tables? Do you have a Join table? Like a AddressToFlyer Table that establishes the relationship between the two tables?
When I have complex queries that need to take place like this where one table can be used by many tables, I create join tables and typically create views that handle the joins and give me the data what I want so I can just do a select in Entity Framework and not worry about the Navigational property, then implement said view in Entity framework like you would a regular table.

Related

Many-to-Many relationship in WPF with EF and SQLite

I'm following this tutorial in order to implement a local database (using SQLite) for my WPF application.
Everything works as it should, although I have a logical problem I don't know how to solve using this approach. I'll simplify it below.
Database-wise, I have 2 tables (A,B) which share a many-to-many relationship, and thus require a JOIN table as well (ABJoin).
In my actual code however, I'd like to use only 2 models: A and B, which each having a list of the other type. Like this:
public class A {
// ...fields
List<B> bList;
}
public class B {
// ...fields
List<A> aList;
}
How can it be implemented in EF+SQLite?
Searching online, I have found some solutions, but nothing that applies to SQLite, so I was not sure how they'd work.
Configure Many-to-Many Relationships in Code-First
If you are using many to many join table then your each class should have a list of the join table.
It cannot work the way you are thinking.
Are you sure that it is a good idea not to have a third entity?
Lets say your two entities were DepartmentStore and Product, a typical example for an n:n relationship. A department store can sell many products and a product may be available in many departments stores. This results in a third entity which connects the two above, in the example above this would something like ProductAvailability.
If you think about it more careful, then you might realize that the new connecting entity might have properties of its own. In my example this might be NumberOfProducts, will states the available quantity of a product in a certain department store.
In my experience, it is quite common for the connecting entity to have a real value that goes beyond just connecting two other entities.
I also took a look at you example which it about Album and Artist entities.
Do you want to make a data model where an Album can be created by more than one Artist?
Entity Framework doesn't have automatic many-to-many mapping.
Instead of this, you can map A and B to intermediate table as one-to-many.
If you are not obliged to use only EF, I suggest to try NHibernate ORM instead.
It has convenient many-to-many mapping and generally more powerful.

Entity Framework with many to many relationship generetad tables

Here's my question. I have 2 models (Person, Event) and with EF and modelbuilder I generate a booking table (with IdPerson and IdEvent as properties).
So in my DB it's correct, I have 3 tables (Person, Event and Booking) with many to many relationship. But I have only 2 models in Visual Studio (Booking doesn't exist because of the self-generated table).
With my Controller I want to write an action for the Person to suscribe to an event and I have to write on my table Booking on the DB but it doesn't exist as a model so I can't do that .
How should I proceede?
Should I create a Booking model and delete my modelbuilder?
When you are using ORMs like EF, you can sit back and let the ORM manage these middle tables.
You can use
person.Events.Add(event)
or
event.People.Add(event)
and EF handles all and inserts a row with personId and eventId in that table.
Here you can find a complete sample:
http://blogs.msdn.com/b/wriju/archive/2011/05/14/code-first-ef-4-1-building-many-to-many-relationship.aspx
I assume this is a model first approach.
The reason for having only 2 objects is that, by default, EF does not create objects for joint tables. What it does create is Navigation Property (Entity Framework - Navigation Property Basics). In one-to-many scenario, a navigation property inside a parent object contains a collection of entities in a foreign / child table. In many-to-many scenario, navigation properties of each entities will simply contain collections of its other entities.

Entity Framework - Manually Add Properties to Many-to-Many Relationship - Model First

Scenario:
As mentioned here, once you add additional properties to a simple join table (many-to-many relationship), it's no longer a hidden association. These questions also address this:
Many-to-Many relationship in Entity Framework with relationship informantion
How can I add properties to an association (relationship) using the Entity Framework
The existing code already uses the simple, automatically hidden navigation properties, and there are some minor customizations to the autogenerated tables, and so I'd like to avoid refactoring the entire project when I alter the underlying relationship table.
Question:
Is there a way so that both the automatic navigation (many-to-many) accessors can remain, but I can also access the relationship entity directly?
I could just write my own accessors selecting from the relationship table, but then they're no longer EntityCollections and thus I'm concerned that I lose whatever magic happens under the hood like tracking, etc.
Can I manually add EntityCollections to entities?
Expectation:
Originally: Product* <-> *Offer
a Product has many Offers (like 50% off, BOGO)
the same Offer could apply to many Products ("Red Shirt" and "Blue Pants" are BOGO)
Desired: Product* <-[sort]-> *Offer
When I list Offers for a Product, I can sort them independently
i.e. "Red Shirt" has "50% off" then "BOGO", but "Blue Pants" shows "BOGO" then "50% off"
then I would want to be able to do:
// original access, do stuff
List<Offer> applicableOffers = currentProduct.Offers.Where(...);
// hit up the join table directly for properties
var applicableOffersInOrder = applicableOffers.OrderBy(o => o.ProductOffers.Sort);
rather than
var applicableOffersInOrder = currentProduct.ProductOffers
.OrderBy(o => o.Sort)
.Offers.Where(...);
I think the easiest way to do it is simply add two properties manually in a non-autogenerated partial class:
partial class Offer
{
public IQueryable<Product> Products
{
get { return this.ProductOffers.Select(x => x.Product); }
}
}
partial class Product
{
public IQueryable<Offer> Offers
{
get { return this.ProductOffers.OrderBy(x => x.Sort).Select(x => x.Offer); }
}
}
This won't help for when you want to add a new ProductOffer, but since you actually have extra data (Sort) you should be doing that via the ProductOffers collection anyway.

Using existing database and EF code-first, mapping a lookup table to entity

I am using entity framework, code first, 4.0, hitting an existing legacy database for read-only access. The database is normalized, so
Table [Event]
[ID]
[Date_Entered]
[Event_Status_Key]
Table [Event_Status]
[Event_Status_Key]
[Event_Status_Description]
My class looks like
public class Event
{
public DateTime DateEntered { get; set; }
public string StatusDescription { get; set; }
}
This is a WCF service layer application.
My two questions:
Is there any easy way to populate the status description without creating a second Dictionary-type object? I've seen questions like this: Entity Framework Mapping to Lookup table, but they seem to be focused on object to object, and I really just want a primitive. I'd prefer using the fluent API as opposed to attributes.
When the data is loaded, is any of the data cached at the code layer? Or does each check on the StatusDescription mean a separate call on the [Event_Status] table?
Edit: A possible (more subjective, which is why I didn't bring it up) third question is how close should the data entities match the database. Is it always a one-to-one field/table? Is what I'm doing (joining two tables into one data entity obejct) bad?
Thanks.
Entity framework expects that you will map both tables as separate entities and use projection in your query:
var query = from e in context.Events
select new WcfEvent // Your original Event class is just DTO
{
DateEntered = e.DateEntered,
StatusDescription = e.EventStatus.EventStatusDescription
};
This example expects correctly one-to-one mapping of your Event and Event_Status tables.
If you need any kind of caching you will have to implement it yourselves. Projected results are not even tracked by the context.

two tables considered as one

I have two tables like this:
Table1(id, name)
Table2(id_of_table_1, code)
I don't need an entity for Table1 or Table2, but one entity for both together:
class Merge{
public virtual long id{get;set;}
public virtual string name{get;set;}
public virtual string code{get;set;}
}
How can I load the tables to the edmx so that they will considered as one?
I don't have any control on the database and I can't create tables or views.
You are looking for advanced mapping called Entity splitting.
I think this is what you're lookig for: How to: Define a Model with a Single Entity Mapped to Two Tables
In short, you need to do this:
Add the two tables as two separate entities to your model
Cut the scalar values from the Table2 entity to the Table1 entity
Delete the Table2 entity
In the Table Mapping options of the Table1 entity, map the Table2-fields to Table2
For a more detailed explanation, you can have a look at this blog post.
Create a function inside your Merge class that writes the properties of your class to the appropriate Table1 and Table2 EDMX objects. Your Merger class should have references to those EDMX objects as internal variables. So this class is like a wrapper for your 2 table objects.

Categories

Resources