Entity Framework 4.1 one to one relationship nullable - entity-framework-4.1

Hello everybody again,
I need some help in this logic for EF 4.1
I have one table with data for a customer. I have also another table with a survey i need to compile when needed.
So initally i could insert a new customer and after some days I'll fill the survey form. Then the relationship MUST be one-to-one and optional (just because this survey could never be compiled for a customer).
I digged in some examples online but i'm really stuck.
Thank you in advance.

Simply define your entities like:
public class Customer
{
public int Id { get; set; }
...
public virtual Survey Survey { get; set; }
}
public class Survey
{
[Key, ForeignKey("Customer")]
public int Id { get; set; }
public virtual Customer Customer { get; set; }
}
If you don't like data annotations remove them and place this into OnModelCreating in your context:
modelBuilder.Entity<Customer>()
.HasOptional(c => c.Survey)
.WithRequired(s => s.Customer);

Related

Relationship with ADO.NET and Mysql

In the database I have two tables, one student and another student address. They have a one-to-one relationship (1: 1).
When I use ado.net, with EF Designer From DataBase, visual studio understands relationship as one for many (1: n).
Entity student, code:
public partial class student
{
public student()
{
this.studentadress = new HashSet<studentadress>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Age { get; set; }
public virtual ICollection<studentadress> studentadress { get; set; }
}
How do I make him understand, and maintain the relationship of (1: 1). And without it creating a collection attribute in the entity, but an object attribute.

Entity Framework - Complex Model using Code First

Good day guys,
I've got quite a specific data model that I'm trying to create in POCO classes, and I've tried so many different approaches and visited so many websites, but none seem to cover my specific example.
So I'm going to throw this out there and hope someone can help me.
I've got products, and products have ingredients. In our business though, these products can get supplied by different vendors, each with a slightly different set of ingredients.
So I've got my base classes:
public class Product
{
public int ProductID { get; set; }
public string ProductNumber { get; set; }
public string Description { get; set; }
public virtual ICollection<Supplier> Suppliers { get; set; }
}
public class Vendor
{
public int VendorID { get; set; }
public string Name { get; set; }
public virtual ICollection<Supplier> Suppliers { get; set; }
}
public class Ingredient
{
public int IngredientID { get; set; }
public string Name { get; set; }
}
public class Supplier
{
public int SupplierID { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<Vendor> Vendors { get; set; }
}
So as you can see, I've gotten as far as realising that my model needs a join entity, because my ingredients come from a specific vendor for a product, I need that join entity called supplier (I think).
This is where I am getting stuck... My product can be supplied by one or more vendors. Each vendor, per product, will have a list of ingredients for that product
I can't even get past whether I need the join entity or not.
What would be awesome was if I could navigate the data structure like this (or something similar):
articles[1].Vendors[3].Ingredients;
Yet again, I don't know enough about Entity Framework to know if this is possible.
The way I'm doing it now feels... wrong. What is the correct way to be doing what I want to do? Do I need the join table or can I somehow navigate the ingredients for a vendor for a product, maybe using the modelbuilder to make the product->vendor->ingredient link required?
Any help would be greatly appreciated!
Edit:
I also think I don't understand enough about Entity Framework's relationship ideas.
So one product can have multiple vendors, which is a 1-to-many relationship. But a Vendor can have many products. So is this actually a many-to-many?
I can definitely model what I want to do on a SQL Express server, but I really want to use Entity Framework. I just need a better understanding of my modelling requirements.
It is not problem of EF. It is common entity-relationship task. You must simply improve your model. You can for example divide Product into two entities: ProductDefinition, ProductInstance
public class ProductDefinition
{
public int ProductID { get; set; }
public string ProductNumber { get; set; }
public string Description { get; set; }
public virtual ICollection<ProductInstance> Instances { get; set; }
}
public class ProductInstance
{
public int ProductInstanceID { get; set; }
public virtual Supplier Supplier { get; set; }
public virtual ProductDefinition Definition { get; set; }
public vritual ICollection<Ingredient> Ingredients { get; set; }
}
In your system you will work with ProductDefinition instead of original Product. This definition is like group of same products and it points to all possible manufacturings of products provided by different suppliers with different ingredients.
I don't know your context but it seems strange to count products with different ingredients as "same".
Why do you use the code first, instead of making the design of the database first? Maybe this will be a bit easier. Additionally i cant see the relation between Vendor and Ingredient, or Product and Ingredient
For my understanding:
It's a new product, when a vendor uses other ingredients?

Entity Framework Code First - Mapping entites from another database to include in model

I've been tasked with creating a sub application of an existing site. The sub application needs to make use of the users in the parent site but this is under a different database.
I'm using Entity Framework code first for the new site. However, I wish to create a mapping between the parent database user table and the new code first database.
Is this possible?
ParantDB.dbo.User
SubDB.dbo.Order
SubDB.dbo.OrderItems
public class Order
{
public int OrderId { get; set; }
public User Customer { get; set; } // Maintains a relationship user table
}
public class User
{
public int UserId { get; set; }
....
}
public class SubSiteContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//???? I Presume I need to do the mapping here??
}
}
Context can be bound only to a single connection string = single database. The workaround for this cab be for example creating database view in your SubDB which will internally hide query to ParentDB.dbo.Users and map this view in the same way as you map tables.

EF 4.1 code-first: How to design and map these entities?

I have 3 entities: Member, AuthenticationToken, and Email.
Each Member may has many AuthenticationTokens
Each AuthenticationToken may has one or zero Email
Each Member may has zero or one PrimaryEmail (from Emails table). Really the PrimaryEmail is one of the AuthenticationTokens's associated Email
So I have:
public class Member {
public int MemberId { get; set; }
public int? PrimaryEmailId { get; set; }
public virtual Email PrimaryEmail { get; set; }
public virtual ICollection<AuthenticationToken> AuthenticationTokens { get; set; }
}
public class AuthenticationToken {
public int AuthenticationTokenId { get; set; }
public int MemberId { get; set; }
public virtual Member Member { get; set; }
public virtual Email Email { get; set; }
}
public class Email {
public int EmailId { get; set; } // is same as AuthenticationTokenId that the email associated with it
}
With design I explained above, I can add Member and AuthenticationToken, but when I want to attach a Email to a Member or AuthenticationToken (or both) I give this error:
The INSERT statement conflicted with the FOREIGN KEY constraint etc.
Is this design correct???
How can I design my tables (and entities) to achieve my purpose?
And how can I map my entities in code-first? Have you any idea please?
I personally use the fluent API in EF 4.1 to configure all of my entities when I don't feel the default conventions will understand me, so I will answer using the fluent API.
Here is how I would set up the models:
public class Member
{
public Member()
{
AuthenticationTokens = new List<AuthenticationToken>();
}
public int MemberId { get; set; }
public virtual Email PrimaryEmail { get; set; }
public virtual ICollection<AuthenticationToken> AuthenticationTokens { get; set; }
}
public class AuthenticationToken
{
public int AuthenticationTokenId { get; set; }
public virtual Email Email { get; set; }
}
public class Email
{
public int EmailId { get; set; }
}
And this is my context and fluent configuration:
public class ExampleApplicationContext : DbContext
{
public ExampleApplicationContext()
: base("ExampleApplicationConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// No cascade on delete because the primary email may be held by an authentication token.
modelBuilder.Entity<Member>()
.HasOptional(x => x.PrimaryEmail)
.WithOptionalDependent()
.Map(x =>
{
x.MapKey("EmailId");
})
.WillCascadeOnDelete(false);
// Cascade on delete because an authentication token not associated with a Member makes no sense.
modelBuilder.Entity<Member>()
.HasMany(x => x.AuthenticationTokens)
.WithRequired()
.Map(x =>
{
x.MapKey("MemberId");
})
.WillCascadeOnDelete();
// No cascade on delete because an email may be held by a Member.
modelBuilder.Entity<AuthenticationToken>()
.HasOptional(x => x.Email)
.WithOptionalDependent()
.Map(x =>
{
x.MapKey("EmailId");
})
.WillCascadeOnDelete(false);
}
public DbSet<Member> Members { get; set; }
}
I will do my best here to explain my reasoning as to why I designed it like this. First of all, it appears that in your model Member should be the root aggregate (the boss of the other entities). What I mean is an Authentication Token makes no sense unless it belongs to a specific Member. An Email also makes no sense alone unless it either belongs to a Member or belongs to an AuthenticationToken. For this reason AuthenticationToken does not have a property to find out what Member it is attached to (to find this out you first need a Member and than just look at its collection). Essentially, everything revolves around a Member object. Without a Member an AuthenticationToken cannot be created. And without a Member or an AuthenticationToken an Email cannot be created.
I'm not entirely sure how comfortable you are with the fluent API in EF 4.1, so if you have any questions leave a comment and I will do my best to answer them. I have also included a small sample application that I used to build and verify the model I presented above. If you want to run the program (it is a small Console app) you just have to modify the connection string in App.config to point to your instance of SQL Server.
One thing that concerns me is the fact that Email can belong to both a Member and an AuthenticationToken. My concern comes from the fact that I had to setup some interesting cascade deletes. I don't know all of your requirements, however, and this setup appears to work just fine so that may not be an issue.
Example Console Application

Applying Domain Model on top of Linq2Sql entities

I am trying to practice the model first approach and I am putting together a domain model. My requirement is pretty simple: UserSession can have multiple ShoppingCartItems.
I should start off by saying that I am going to apply the domain model interfaces to Linq2Sql generated entities (using partial classes). My requirement translates into three database tables (UserSession, Product, ShoppingCartItem where ProductId and UserSessionId are foreign keys in the ShoppingCartItem table). Linq2Sql generates these entities for me. I know I shouldn't even be dealing with the database at this point but I think it is important to mention.
The aggregate root is UserSession as a ShoppingCartItem can not exist without a UserSession but I am unclear on the rest. What about Product? It is defiently an entity but should it be associated to ShoppingCartItem?
Here are a few suggestion (they might all be incorrect implementations):
public interface IUserSession {
public Guid Id { get; set; }
public IList<IShoppingCartItem> ShoppingCartItems{ get; set; }
}
public interface IShoppingCartItem {
public Guid UserSessionId { get; set; }
public int ProductId { get; set; }
}
Another one would be:
public interface IUserSession {
public Guid Id { get; set; }
public IList<IShoppingCartItem> ShoppingCartItems{ get; set; }
}
public interface IShoppingCartItem {
public Guid UserSessionId { get; set; }
public IProduct Product { get; set; }
}
A third one is:
public interface IUserSession {
public Guid Id { get; set; }
public IList<IShoppingCartItemColletion> ShoppingCartItems{ get; set; }
}
public interface IShoppingCartItemColletion {
public IUserSession UserSession { get; set; }
public IProduct Product { get; set; }
}
public interface IProduct {
public int ProductId { get; set; }
}
I have a feeling my mind is too tightly coupled with database models and tables which is making this hard to grasp. Anyone care to decouple?
Looks like you are on the right track. Half of the whole "doing DDD right" is having the right base classes. Have a look at this great DDD applied to C# resource:
http://dddpds.codeplex.com/
The source code is available and is very readable.
So, with regards to having ID in the model. The ID is a database thing and the usual approach is to keep all persistence out of the Model and restrict the model to the business logic. However, one normally makes an exception for the identifier and buries it in the Model base class like so:
public class ModelBase {
protected readonly object m_Key;
public ModelBase(object key) {
m_Key = key;
}
}
This key is used by your persistence layer to talk to the database and is opaque. It's considered quite OK to downcast the key to the required type, because you know what it is.
Also, the Domain Objects are pretty much on the bottom of your architecture stack (just above the Infrastructure layer). This means that you can make them concrete classes. You will not have multiple implementations of the domain models, so the interfaces are unnecessary, which is what Domain Driven Design is about - Domain first.
public Class UserSession : ModelBase {
public UserSession(Guid Id):base(Id) {}
public Guid Id { get{ return m_Key as Guid;} }
public IList<ShoppingCartItem> ShoppingCartItems{ get; set; }
}
public class ShoppingCartItem : ModelBase {
public ShoppingCartItem ():base(null) {}
public UserSession UserSession { get; set; }
public Product Product { get; set; }
}
Typical shopping cart or customer-order examples prefer making UserSession (or Order) the root of aggregate. Individual items should be children of this session/order. It is up you whether individual items in the cart should have a meaningful id. I would prefer no, since 5 widgets in the cart are indistinguishable from another 5 widgets. Hence, I would model cart items as a collection of value objects.
Common problem with shopping cart items is whether they should include price, or not. if you include price, you will have your cart independent from changes of product price. It is very desirable if you want to store you cart for historical reasons since it is valuable to know how much items in the cart cost according to price when they were bought, not according to current.
Product should form definitively an aggregate by itself. Period.
Now, I don't know if all of this is easily implementable in LINQ to SQL, but you can try.