NCommon 1.1 and EF4 - entity-framework-4

I am new to NCommon and am looking for an example project to get started.
I am using EF4.
I assume one needs to use EF4 with POCOs?
Thanks for any help.

NCommon.Configure.Using(new StructureMapContainerAdapter(ObjectFactory.Container))
.ConfigureState<DefaultStateConfiguration>()
.ConfigureData<EFConfiguration>(config => config.WithObjectContext(
() =>
{
SiteContext db = new SiteContext(ConfigurationManager.ConnectionStrings["TestTheBest"].ConnectionString);
if (Transaction.Current != null )
{
db.Context.Connection.Open();
}
return db.Context;
}))
.ConfigureUnitOfWork<DefaultUnitOfWorkConfiguration>(config => config.AutoCompleteScope());
public class SiteContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Test> Tests { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<Section> Sections { get; set; }
public DbSet<Answer> Answers { get; set; }
public DbSet<GlobalSettings> GlobalSettings { get; set; }
public DbSet<PassageTest> PassageTest { get; set; }
public DbSet<PassageTestAnswer> PassageTestAnswer { get; set; }
public DbSet<SaaSUser> SaaSUser { get; set; }
public SiteContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
Context.SavingChanges += new EventHandler(Context_SavingChanges);
}
void Context_SavingChanges(object sender, EventArgs e)
{
if(Context.Connection.State==ConnectionState.Open)
Context.Connection.Close();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasMany(x => x.Invitations).WithRequired(x=>x.user).WillCascadeOnDelete(true);
modelBuilder.Entity<User>().HasMany(x => x.PassageTests).WithRequired(x => x.user).WillCascadeOnDelete(true);
modelBuilder.Entity<PassageTest>().HasMany(x => x.PassageTestAnswers).WithRequired(x => x.passageTest).WillCascadeOnDelete(true);
// modelBuilder.Entity<Company>().HasMany(x => x.Users).WithRequired(x => x.company).WillCascadeOnDelete(true);
modelBuilder.Entity<Question>().HasMany(x => x.Answers).WithRequired(x => x.question).WillCascadeOnDelete(true);
modelBuilder.Entity<Question>().HasMany(x => x.PassageTestAnswers).WithRequired(x => x.question).WillCascadeOnDelete(true);
modelBuilder.Entity<Test>().HasMany(x => x.Invitations).WithRequired(x => x.test).WillCascadeOnDelete(true);
modelBuilder.Entity<Test>().HasMany(x => x.PassageTests).WithRequired(x => x.test).WillCascadeOnDelete(true);
modelBuilder.Entity<Test>().HasMany(x => x.Sections).WithRequired(x => x.test).WillCascadeOnDelete(true);
modelBuilder.Entity<Client>().HasMany(x => x.Tests).WithRequired(x => x.client).WillCascadeOnDelete(true);
}
public ObjectContext Context
{
get { return ((IObjectContextAdapter)this).ObjectContext; }
}
}

Related

Apply cascade delete in one to many relationship

If I have two required foreign keys in class and these keys compose this class primary key and we have another class contain list of this class how to implement cascade delete in this case entity framework code first
public class Post
{
public int Id { get; set; }
public string ClientName { get; set; }
public JobType JobType { get; set; }
public double JobBudget { get; set; }
public DateTime CreationDate { get; set; }
public string JobDescription { get; set; }
public bool IsAccepted { get; set; }
public string ClientId { get; set; }
public List<Proposal> Proposals { get; set; }
public ApplicationUser Client { get; set; }
}
public class Proposal
{
public string FreelancerId { get; set; }
public int PostId { get; set; }
public bool IsAccepted { get; set; }
public ApplicationUser Freelancer { get; set; }
public Post Post { get; set; }
}
public PostConfigurations()
{
Property(p => p.ClientName)
.IsRequired();
Property(p => p.JobType)
.IsRequired();
Property(p => p.JobBudget)
.IsRequired();
Property(p => p.CreationDate)
.IsRequired();
Property(p => p.JobDescription)
.IsRequired()
.HasMaxLength(255);
HasOptional(p => p.Proposals)
.WithOptionalDependent()
.WillCascadeOnDelete(true)
}
public class ProposalConfigurations : EntityTypeConfiguration<Proposal>
{
public ProposalConfigurations()
{
HasKey(p => new { p.FreelancerId, p.PostId });
Property(p => p.FreelancerId)
.IsRequired();
Property(p => p.PostId)
.IsRequired();
}
}
I tried many things, but failed, can you please help?

EF6 Code first Composite Foreign key with Fluent API

I am having trouble creating One-one(zero) Foreign key relationship on code first EF6 fluent API
My Entities are
public class Invoice
{
public int AccountID { get; set; }
public int InvoiceID { get; set; }
public decimal Amount { get; set; }
public Refund Refund { get; set; }
internal static void ConfigureModel(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Invoice>()
.HasKey(e => new { e.AccountID, e.InvoiceID });
}
}
public class Refund
{
public int AccountID { get; set; }
public int RefundID { get; set; }
public decimal Amount { get; set; }
public int InvoiceID { get; set; }
public Invoice Invoice { get; set; }
internal static void ConfigureModel(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Refund>()
.HasKey(e => new { e.AccountID, e.RefundID });
modelBuilder.Entity<Refund>()
.HasRequired(e => e.Invoice )
// .HasForeignKey(e => new { e.AccountID, e.InvoiceID});
}
}
I can't define the composite foreign key on Refund table using fluent API
If I change the
public Refund Refund { get; set; }
to
public ICollection<Refund> Refund{ get; set; }
Then I can add this relation as
modelBuilder.Entity<Refund>()
.HasRequired(e => e.Invoice)
.WithMany(e => e.Refund)
.HasForeignKey(e => new { e.AccountID, e.InvoiceID});

Automapper not mapping my list properties

In my MVC5 project I use automapper to map my viewmodels to my models. But it seems that I'm doing something wrong, because not all my properties are mapped.
Here is my View Model
public class PlanboardViewModel
{
public int Id { get; set; }
[Display(Name = "Titel")]
public string Title { get; set; }
[Display(Name = "Omschrijving")]
public string Description { get; set; }
[Display(Name = "Verzoektype")]
public int AbsenceTypeId { get; set; }
public List<PlanboardEventMapViewModel> EventMap { get; set; }
public List<PlanboardEventDetail> EventDetails { get; set; }
public List<PlanboardRequest> PlanboardRequests { get; set; }
}
I use a separate class for my profiles:
public class PlanboardMappingProfile : Profile
{
protected override void Configure()
{
//CreateMap<AbsenceType, AbsenceTypeViewModel>();
//.ForAllMembers(opt => opt.Condition(s => !s.IsSourceValueNull));
CreateMap<PlanboardViewModel, Planboard>()
.ForMember(dest => dest.CSVHPlanboardEventDetail, opt => opt.MapFrom(src => src.EventDetails))
.ForMember(dest => dest.CSVHPlanboardEventMap, opt => opt.MapFrom(src => src.EventMap))
.ForMember(dest => dest.CSVHPlanboardRequest, opt => opt.MapFrom(src => src.PlanboardRequests));
CreateMap<PlanboardEventMapViewModel, PlanboardEventMap>();
}
}
In my repository I have the following code:
public int Create(PlanboardViewModel planboardViewModel)
{
try {
// map the viewmodel to the planboard model
// Map the planboards to the view model
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<PlanboardMappingProfile>();
cfg.CreateMap<PlanboardViewModel, Planboard>();
cfg.CreateMap<PlanboardEventMapViewModel, PlanboardEventMap>();
});
IMapper mapper = config.CreateMapper();
Planboard planboard = mapper.Map<Planboard>(planboardViewModel);
// Some more code here
When I submit the page and use the debugger, It shows that planboardViewModel has a list of values for PlanboardEventMapViewModel, PlanboardEventDetail, PlanboardRequest. The system is not telling me that there are any errors. When I check planboard after the mapping, it does not show any values for CSVHPlanboardEventDetail, CSVHPlanboardEventMap and CSVHPlanboardRequest.
EDIT
My PlanboardModel is created DB First EF6:
public partial class Planboard
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Planboard()
{
this.CSVHPlanboardEventDetail = new HashSet<PlanboardEventDetail>();
this.CSVHPlanboardEventMap = new HashSet<PlanboardEventMap>();
this.CSVHPlanboardRequest = new HashSet<PlanboardRequest>();
}
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int StatusID { get; set; }
public Nullable<int> AbsenceTypeID { get; set; }
public virtual AbsenceType AbsenceTypes { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PlanboardEventDetail> CSVHPlanboardEventDetail { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PlanboardEventMap> CSVHPlanboardEventMap { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PlanboardRequest> CSVHPlanboardRequest { get; set; }
}

NHibernte CreateAlias for 2 multiply class

I have 3 classes: Book, Genre, Authors
public class Book {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual int MfRaiting { get; set; }
public virtual int PageNumber { get; set; }
public virtual IList<Genre> Genres { get; set; }
public virtual Series Series { get; set; }
public virtual Mind Mind { get; set; }
public virtual IList<Author> Authors { get; set; }
public Book() {
Genres = new List<Genre>();
Authors = new List<Author>();
}
}
public class Genre {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Book> Books { get; set; }
public Genre() {
Books=new List<Book>();
}
}
public class Author {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string SurName { get; set; }
public virtual string Biography { get; set; }
public virtual IList<Book> Books { get; set; }
public Author() {
Books=new List<Book>();
}
}
And his classMaps
public class BookMap : ClassMap<Book> {
public BookMap() {
Id(x => x.Id);
Map(x => x.Name);
HasManyToMany(x => x.Genres)
.Cascade.All()
.Table("Book_Genre");
HasManyToMany(x => x.Authors)
.Cascade.All()
.Table("Book_Author");
References(x => x.Series);
HasOne(x => x.Mind).Constrained();
}
}
public class GenreMap : ClassMap<Genre> {
public GenreMap() {
Id(x => x.Id);
Map(x => x.Name);
HasManyToMany(x => x.Books)
.Cascade.All()
.Inverse()
.Table("Book_Genre");
}
}
public class AuthorMap : ClassMap<Author> {
public AuthorMap() {
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.SurName);
Map(x => x.Biography);
HasManyToMany(x => x.Books)
.Cascade.All()
.Inverse()
.Table("Book_Author");
}
}
When i try write in code
var criteria = session.CreateCriteria();
criteria.CreateAlias("Genres", "genre", JoinType.LeftOuterJoin);
it works well, but when i do so
public ActionResult Index()
{
var criteria = session.CreateCriteria<Book>();
criteria.CreateAlias("Genres", "genre", JoinType.LeftOuterJoin);
criteria.CreateAlias("Authors", "author", JoinType.LeftOuterJoin);
criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());
}
i see exception Cannot simultaneously fetch multiple bags. How can I get result of that criteria?
Thank
I resolve this problem! I replace IList on ISet, and replace new List<"Class"> on new HashSet<"Class">
I read this problem here.
http://developer-should-know.tumblr.com/post/118012584847/jpa-fetching-strategies Only one collection that is fetched using JOIN strategy can be of type List, other collection must be of type Set. Otherwise an exception will be thrown:
HibernateException: cannot simultaneously fetch multiple bags

DataContext is missing properties in where statement

Could some tell me why I have no properties in my where statements after using a select statement for e.g.
db.Select(x => x.Lft).Where(x => x.DepartmentId == id);
// missing properties in the where clause
And could you help me correct my code to implement it please leave me an example of what to do to implement this thanks
Classes:
public class Department
{
public Department()
{
Products = new List<Product>();
}
public long DepartmentId { get; set; }
[Required(ErrorMessage="Please enter a name for the departments.")]
[DataType(DataType.Text)]
public string Name { get; set; }
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please enter a valid url for the department.")]
public string Url { get; set; }
public int Lft { get; set; }
public int Rgt { get; set; }
public bool MenuItem { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
my DataContext class
internal class DepartmentsTypeConfiguration : EntityTypeConfiguration<Department>
{
public DepartmentsTypeConfiguration()
{
Property(department => department.DepartmentId)
.HasColumnName("DepartmentId")
.HasDatabaseGeneratedOption(databaseGeneratedOption: DatabaseGeneratedOption.Identity);
Property(department => department.Name)
.HasColumnName("Name")
.IsRequired();
HasKey(key => key.DepartmentId)
.HasMany(x => x.Products)
.WithRequired(x => x.Department)
.WillCascadeOnDelete(true);
}
}
public class LeapFrogDataContext : DbContext
{
public DbSet<Department> Departments { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ProductSpecification> ProductSpecifications {get; set;}
public DbSet<Specification> Specifications { get; set; }
/**/
static LeapFrogDataContext()
//: base("name=LeapFrogDataConnection")
{
//Database.SetInitializer(new LeapFrogInitializer());
//Database.SetInitializer(new DropCreateDatabaseIfModelChanges<LeapFrogDataContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DepartmentsTypeConfiguration());
modelBuilder.Configurations.Add(new ProductsTypeConfiguration());
modelBuilder.Configurations.Add(new SpecificationsTypeConfiguration());
modelBuilder.Configurations.Add(new ProductSpecificationsTypeConfiguration());
base.OnModelCreating(modelBuilder);
}
}
db.Select(x => x.Lft) returns a list of int so in the where clause you will not access any property.
I guess you may switch select and where to achieve what you want. Assume db is the actual context.
db.Where(x => x.DepartmentId == id).Select(x => x.Lft)
That's a bit weird. Normally it should look like
db.context.Departments.Where(x => x.DepartmentId == id).Select(x => x.Lft)

Resources