Shortly,
Here's a code. It doesn't work.
I try to insert property with same key in both table.
DevExpress tickets doesn't resolve it also First Ticket and Second Ticket
See First Ticket link. see last reply. That what I do here. not working.
DevExpress First Ticket Last Comment-> To implement this relationship, do not add any relationship object from the designer's toolbox. Instead, create two properties - a property of the MasterBusinessPartner type for the MasterCustomers class and a property of the MasterCustomer type for the MasterBusinessPartner class. This will be sufficient to generate the code you demonstrated in the first code snippet. If you want to implement additional synchronization logic, similar to what is shown in the How to: Implement One-to-One Relationships topic, you can override the OnChanged method, as described in the ORM Wizard one-to-one relation partial classes ticket.
My Schema ( 2 Tables one-to one) Each menu only have single MenuBLOB row.
[Persistent("Menu")]
public class Menu : XPLiteObject
{
[Key, Association("kk")]
public MenuBLOB MenuKey { get; set; }
public long MenuID { get; set; }
public Menu(Session session) : base(session) { }
public Menu(Session session, XPClassInfo classInfo) : base(session, classInfo) { }
}
[Persistent("MenuBLOB")]
public class MenuBLOB : XPLiteObject
{
public long MenuID { get; set; }
public string Base64Value { get; set; }
[Key, Association("kk")]
public Menu MenuKey { get; set; }
public MenuBLOB(Session session) : base(session) { }
public MenuBLOB(Session session, XPClassInfo classInfo) : base(session, classInfo) { }
}
Exception of type 'System.StackOverflowException' was thrown
Related
I have two sets of objects: Coupon and DiscountScheme.
Each have a connected object of {Type}Action, and identical configurations.
When making a request for Coupon, I do not get anything back,
but the same query for DiscountScheme works as expected
A condensed version of the classes (The full code and sql for the tables can be found here):
public class CouponAction
{
public int Id { get; set; }
public virtual Coupon Coupon { get; set; }
}
public class Coupon
{
public int Id { get; set; }
public virtual CouponAction Action { get; set; }
}
public class DiscountSchemeAction
{
public int Id { get; set; }
public virtual DiscountScheme DiscountScheme { get; set; }
}
public class DiscountScheme
{
public int Id { get; set; }
public virtual DiscountSchemeAction Action { get; set; }
}
The configuration:
public class CouponActionMap : EntityTypeConfiguration<CouponAction>
{
public CouponActionMap()
{
ToTable("CouponAction");
}
}
public class CouponMap : EntityTypeConfiguration<Coupon>
{
public CouponMap()
{
ToTable("Coupon");
HasRequired(c => c.Action);
}
}
public class DiscountSchemeActionMap : EntityTypeConfiguration<DiscountSchemeAction>
{
public DiscountSchemeActionMap()
{
ToTable("DiscountSchemeAction");
}
}
public class DiscountSchemeMap : EntityTypeConfiguration<DiscountScheme>
{
public DiscountSchemeMap()
{
ToTable("DiscountScheme");
HasRequired(ds => ds.Action);
}
}
The query I am trying to make:
using(var context = new Context()/* My database context, using a custom wrapper framework*/)
{
Console.WriteLine(context.Coupons.ToList()); // nothing
Console.WriteLine(context.DiscountSchemes.ToList()); // the contents of the table
}
If I query the actions table, I do get the contents, but again for CouponAction I do not get the connected Coupon, and for DiscountScheme it works as expected.
The issue is with your 1-to-1 relationship. By default EF expects a 1-to-1 to be using the PKs on both tables. By putting a CouponID on your CouponAction you are not setting a 1-to-1 relationship, you are setting a 1-to-many/many-to-1. Nothing stops several CouponAction records from having the same CouponId. You could put a unique constraint on CouponID, but if that were the case then you may as well have the CouponAction's PK to be the CouponID. Hence, this is why I don't advise using "Id" as a PK name, but rather CouponId vs. DiscountId, etc.
If the relationship between coupon and action is truly 1-to-1 then get rid of the CouponId on the Action table, and ensure you're using the same ID value across both tables for the related records. You can test this by changing your mapping to configure EF to use CouponId on the CouponAction as it's PK. Once you do that, you should see your related records coming up.
Alternatively you can establish a many to 1 relationship (HasOne.WithMany()) from Action to Coupon, but no return reference without a CouponActionId on Coupon. Or you can set up a 1-to-many where Coupon contains an ICollection<CouponAction> CouponActions even though you intend to only have one action per coupon. But if it is 1-to-1 then I would highly recommend using the same PK value across both tables.
I want to reuse the same many-to-many relationship table (FileInEntity) for several other objects (Course, Lecture, Game), since they all can have files. Since we have to manually create the many-to-many relationships by creating a join entity, I want to reuse the join entity for the objects (Course, Lecture, Game).
If we look at the table structure, I would like to have the following:
Course: Id, ...
Lecture: Id, ...
Game: Id, ...
FileInEntity: EntityId (this can be either Course.Id, Lecture.Id or Game.Id), FileId
File: Id, ...
(File is base class type with two derived types: Image and Audio)
When I try this approach in .NET Core, I receive the following error message:
Entity type 'FileInEntities' is in shadow-state. A valid model requires
all entity types to have corresponding CLR type.
Is this even possible?
This is my setup:
ModelBase.cs
public class ModelBase
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
}
Course.cs
[Table("Courses")]
public class Course : ModelBase
{
private ICollection<FileInEntity> IconsInCourse { get; set; } = new List<FileInEntity>();
[NotMapped]
public File Image => IconsInCourse.Select(e => e.File).FirstOrDefault();
}
Lecture.cs
// Same as Course.cs
Game.cs
// Same as Course.cs
FileInEntity.cs
[Table("FilesInEntities")]
public class FileInEntity
{
public Guid FileId { get; set; }
public Guid EntityId { get; set; }
public virtual ModelBase Entity { get; set; }
public virtual File File { get; set; }
}
File.cs
[Table("Files")]
public class File : ModelBase
{
// This is the property for which the error occured
private ICollection<FileInEntity> FileInEntities { get; set; } = new List<FileInEntity>();
public IEnumerable<ModelBase> Entities => FileInEntities.Select(e => e.Entities);
}
FilesInEntitiesMap.cs (Relationship Configuration)
builder.HasOne(p => p.Entity)
.WithMany()
.HasForeignKey(k => k.EntityId);
builder.HasOne(p => p.File)
.WithMany()
.HasForeignKey(k => k.FileId);
FileMap.cs
// This is the key to which the error references to
builder.HasMany("FileInEntities")
.WithOne("Entity")
.HasForeignKey("EntityId");
You won't be able to use the base class ModelBase as the object in the mapping class because c# wont know the actual type coming back from the db. You can look at table per hierarchy inheritance, but I'm still not sure you would be able to use that in a mapping table either. Here is a good article
If your Course.cs, Lecture.cs, and Game.cs are the same and the only difference is type, you could combine them into one class and add an enum property to set the type.
public enum EntityType{
Game = 1,
Lecture = 2,
Course = 3
}
public class MyEntity : ModelBase{
private ICollection<FileInEntity> Icons { get; set; } = new List<FileInEntity>();
[NotMapped]
public File Image => Icons.Select(e => e.File).FirstOrDefault();
public EntityType EntityType {get;set;} //course, lecture, or game
}
When you care about the type just use a where clause.
Be sure to use Fluent Api in DbContext's OnModelCreating to determine One to One relationship for this tables. (and be sure again correct reference properties are selected)
Missing parts of your codes.
public class ModelBase
{
[Key]// add for primary key
//set none always for primary keys (because guid has no auto increment)
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
}
[Table("Files")]
public class File : ModelBase
{
//make it public
public ICollection<FileInEntity> FileInEntities { get; set; } = new List<FileInEntity>();
[NotMapped] //set not mapped
public IEnumerable<ModelBase> Entities => FileInEntities.Select(e => e.Entities);
//do it same changes for `Lacture.cs`, `Game.cs` and `Course.cs`...
}
I am working on Login page creating in C# using Code First approach , in this I am getting lot of errors while trying to execute the code. I am a fresher and new to this .
Can you please review my code and help me what I missed in this ?
Rule are not creating and getting the multiple errors. Your help would help me to understand what went wrong in this.
My Class "Class1.cs"
public class Login
{
[Required]
public string username { get; set; }
[Required]
public string password{ get; set; }
}
}
public class LoginContext : DbContext
{
public LoginContext() : base("LoginDBConnectionString")
{
Database.SetInitializer<LoginContext>(new DropCreateDatabaseIfModelChanges<LoginContext>());
}
public DbSet<username> username { get; set; }
public DbSet<password> password { get; set; }
}
Context.cs
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Data.Entity;
using Jquery1.Models;
namespace Jquery1.Models
{
public class Logincontext: DbContext
{
public Logincontext () : base ("LoginDBConnectionString")
{
}
public DbSet<Login> Logins{ get; set; }
}
}
class program
{
static void Main(string[] args)
{
using (var ctx = new Logincontext())
{
ctx.Database.Create();
}`enter code here`
}
}
Hi Let me explain this using fluent api bear with me a little please,
Create Your DbContext First:
public class MyDbContext : DbContext
{
public MyDbContext()
: base("name=MyConnection")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, YourApplication.Migrations.Configuration>("MyConnection"));
}
public DbSet<Users> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//here you can MAP Your Models/Entities, but i am going to show you something more interesting. so keep up.
modelBuilder.Configurations.Add(new UsersMap());
}
}
Create a Migration Folder in your app root And make Configuration class there(Why?! so that everytime you made a change migration of EF will update the Tables for you):
internal sealed class Configuration : DbMigrationsConfiguration<YourApplication.Infrastructure.Data.MyDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
//this feature on true can result in unwanted/unexpected dataloss
AutomaticMigrationDataLossAllowed = true;
ContextKey = "YourApplication.Infrastructure.Data.MyDbContext";
}
protected override void Seed(YourApplication.Infrastructure.Data.MyDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
Now Go on And Create Your POCO Classes. I try to write my codes very clean. That's why when for example i made a Model like below, i create an EntityBase for every Id:
public class EntityBase
{
public int Id { get; set; }
}
And Implement it to my Model :
public class User: EntityBase
{
public string Example1{ get; set; }
public string Example2{ get; set; }
public string Example3{ get; set; }
}
And For Mapping I Create another Class like below and use Fluent Api:
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
//declaring the table name
ToTable("TblUser");
//declaring primary key of the table
HasKey(x => x.Id);
//declaring a property from poco class is required
Property(x => x.Example1)
.IsRequired();
//etc
}
}
be aware if you are using fluent api, you Shouldn't use Data Annotations. Happy Coding.
Entity frame-work uses a concept of standards-or-else. If you want your items fairly standard, you don' have to provide a lot of information. If you want your tables to have different names, or your columns to be different than standard you'll have to provide extra information using either Attributes (the method you use) or fluent API.
Every class that should become a table should have an Primary key. The default is to give your class a property Id, or to give the property the name of your class followed by Id:
public class Login
{
public int Id {get; set;}
public string UserName {get; set;}
public string Password {get; set;}
}
public class MyDbContext : DbContext
{
public DbSet<Login> Logins {get; set;}
}
This should be enough to give you a table with the default name, which is the plural of your class name Logins. Each record in the table has three columns:
Id: the primary key
UserName: a string, which in this case may be null
PassWord: a string which may be null.
Your Requires attribute will ensure that your UserName and Property are not null, but they won't prevent them being empty. I'm not sure that's enough for you.
Instead of Id your are free to use LoginId as foreign key:
public int LoginId {get; set;}
You'll see both methods used. Both have their advantages. The use of Id shows you immediately which property is the primary key. LoginId could also be used as foreign key. The name LoginId alone is not enough to see whether it is a primary key or a foreign key.
The defaults are usually plurals for collections of items where the item is the singular form. Here you'll see Login as class, and Logins as a set of objects of this class.
The article that helped me a lot to get on track using Entity Framework was this entity framework tutorial
The tutorial tells you about how to use defaults, how to create one-to-many relations with foreign keys, many-to-many, various inheritance strategies, and what to do if you are not satisfied with a default model.
I have a class Ricevuta which holds a collection of VoceRicevuta:
public partial class Ricevuta : GestPreBaseBusinessObject
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Id { get; set; }
...
[InverseProperty("Ricevuta")]
public virtual ObservableListSource<VoceRicevuta> Voci { get; set; }
}
A VoceRicevuta holds optional references to different classes, let's consider only the one to Prestazione class:
public partial class VoceRicevuta
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Id { get; set; }
public long IdRicevuta { get; set; }
....
public virtual Prestazione Prestazione { get; set; }
[ForeignKey("IdRicevuta")]
public virtual Ricevuta Ricevuta { get; set; }
}
Ok, the problem now is the following: I create an Instance of Prestazione (let's call it PreInst) and save it to the database. I detach PreInst from that DbContext instance.
Then, I pass PreInst to another form (another DbContext - I must do that), create a Ricevuta, a VoceRicevuta (added to the just created Ricevuta) and assign PreInst to VoceRicevuta Prestazione property. I also made some changes to PreInst.
Now I want to save to database the new Ricevuta, the new VoceRicevuta, its relation to PreInst and the changes to PreInst.
I run the following:
db.UpdateGraph(Ricevuta, map =>
map.OwnedCollection(ric => ric.Voci,
with => with
.OwnedEntity(voce => voce.Prestazione)
));
But i get the error:
"Violation of PRIMARY KEY constraint 'PK_dbo.Prestazioni'. Cannot insert duplicate key in object 'dbo.Prestazioni'. Vlue of duplicate key: (12115)"
I can't understand why! Isn't Graph diff purpose cheching if any part of the graph is already present in Db and behave consquently?
I tried to attach PreInst to DbContext before running the code above and saving. Now the error thrown is:
Multiplicity constraint violated. The role 'Prestazione_VoceRicevuta_Source' of the relationship 'Gestione_Prestazioni.Prestazione_VoceRicevuta' has multiplicity 1 or 0..1.
Any hint?
I have two versions of an almost identical database. Below I have created an Example table to demonstrate the basic differences, namely the ID column has changed from an Integer Identity to a GUID and various properties have been updated, in the Example archived has been replaced with readOnly and hidden:
Legacy version:
CREATE TABLE Example
(
--Data Identity (maps to DbId in the example code)
Id int IDENTITY PRIMARY KEY,
--Example columns
SomeValue varchar(50),
AnotherValue int,
--Data Properties
Archived bit
)
New version:
CREATE TABLE Example
(
--Data Identity (maps to DbId in the example code)
Id uniqueidentifier PRIMARY KEY,
--Example columns
SomeValue varchar(50),
AnotherValue int,
--Data Properties
ReadOnly bit,
Hidden bit
)
I need to be able to use an O/R mapper such as NHibernate to connect to one or other of these database versions. I would like to be able to tell the application which version to use through settings in a configuration file.
My initial plan was to create a common interface for the business logic and use an IoC container such as Unity to swap between the relevant concrete classes in the configuration file.
Below is an example of the code I created to test this theory:
public interface IDataIdentity
{
object Id { get; }
}
public class LegacyDataIdentity : IDataIdentity
{
public virtual long DbId { get; set; }
public object Id
{
get { return DbId; }
}
}
public class NewDataIdentity : IDataIdentity
{
public virtual Guid DbId { get; set; }
public object Id
{
get { return DbId; }
}
}
public interface IDataProperties
{
bool ReadOnly { get; set; }
bool Hidden { get; set; }
}
public class LegacyDataProperties : IDataProperties
{
public virtual bool Archived { get; set; }
public bool ReadOnly
{
get { return Archived; }
set { Archived = value; }
}
public bool Hidden
{
get { return Archived; }
set { Archived = value; }
}
}
public class NewDataProperties : IDataProperties
{
public virtual bool ReadOnly { get; set; }
public virtual bool Hidden { get; set; }
}
public class DataItem
{
public DataItem(IDataIdentity dataIdentity, IDataProperties dataProperties)
{
DataIdentity = dataIdentity;
DataProperties = dataProperties;
}
public IDataIdentity DataIdentity { get; set; }
public IDataProperties DataProperties { get; set; }
}
public class Example : DataItem
{
public Example(IDataIdentity dataIdentity, IDataProperties dataProperties)
: base(dataIdentity, dataProperties)
{
}
public virtual string SomeValue { get; set; }
public virtual int AnotherValue { get; set; }
}
Can anyone advise if this is possible (specifically with Unity and NHibernate) and if so how to create the relevant NHibernate mapping files?
Alternatively, can anyone suggest any solution to the problem using any other methods or other IoC and O/R mapping tools (commercial or open source)?
Many thanks,
Paul
Why not abstract your data provider, implementing 2 versions (one with nhibernate mappings for the legacy data item, and one for the new data item).
To paraphrase your code slightly (simplified for clarity):
public abstract class AbstractData
{
public abstract string SomeValue { get; set; }
public abstract bool ReadOnly { get; set; }
//etc.
}
public interface IDataProvider
{
AbstractData Get(object id);
}
public class LegacyData : AbstractData
{
// Implement AbstractData, and
public virtual long Id { get { return m_Id; } set { m_Id = value; };
private long m_Id;
}
public class LegacyDataNHibernateProvider : IDataProvider
{
public LegacyDataProvider()
{
// Set up fluent nhibernate mapping
}
public AbstractData Get(object id)
{
// Interpret id as legacy identifier, retrieve LegacyData item, and return
}
};
// Same again for new data provider
This way, you aren't tied to nhibernate (or a database, for that matter), and you can specify concrete classes with correctly typed identifiers (which nhibernate can handle). This is the approach I'm taking, where I currently have to map against an existing database's SPs, but will later migrate to a new ORM-based system.
Maybe I'm not understanding your question correctly, but it sounds to me like you need to implement something like the "Factory Pattern".
I recently used the factory pattern to code (c#) to two data layers when the company I work for was switching from JDE to SAP. I was able to flip a config switch to switch between the two data layers, and the GUI wouldn't know any different.
Here's a couple links I found:
http://msdn.microsoft.com/en-us/library/ms954600.aspx
http://www.allapplabs.com/java_design_patterns/factory_pattern.htm
http://en.wikipedia.org/wiki/Abstract_factory_pattern
As far as NHibernate goes, I'm not familiar with it... sorry. Hope this helps.
Hard to recommend without knowing the full picture, but.... You can create an abstruction in the SPs by having SP return identical dataset for both table structures.
Another abstruction I am thinking of, is you can actually specify different hybernate mapping files, and initialize Hibernate with a different file depending on what database you connect to.