2016-06-01 9 views
0

Ich habe eine Companies-Tabelle einer Company-Klasse zugeordnet und eine Websites-Tabelle einer Website-Klasse zugeordnet. Mein Unternehmen Tabelle ist im Grunde nicht bewegen, aber ich versuche, eine neue Website-Datensatz mit dem folgende einfügen:NHibernate fügt neuen Datensatz mit einer Null-Viele-zu-Eins-Zuordnung ein

var website = new Website 
{ 
    Active = true, 
    SiteRoot = "example.com", 
    CompanyId = 100  
}; 
var repo = new WebsiteRepository(); 
repo.Add(website); 

Die Website-Klasse hat eine Eigenschaft, die CompanyID, was in den Unternehmen auf die ID-Spalte ist abbildet zurück Tabelle, aber da die Website-Klasse eine Viele-zu-Eins-Zuordnung hat, versucht sie, die website.Company.Id-Eigenschaft in die Tabelle (die null ist) einzufügen, anstatt die website.Id-Eigenschaft zu übernehmen.

Es sind keine Fremdschlüssel beteiligt, da die Tabellen in 2 separaten Datenbanken enthalten sind.

Dies ist der Fehler Ich erhalte:

NHibernate.Exceptions.GenericADOException: nicht einsetzen konnte: [Models.Website] [SQL: INSERT INTO Database1.dbo.Websites (CompanyID, siteRoot, Aktiv) WERTE (?,?,?); select SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException: Der Wert NULL kann nicht in die Spalte 'CompanyID' eingefügt werden, Tabelle 'Database1.dbo.Websites'; Spalte erlaubt keine Nullen. INSERT schlägt fehl.

NHibernate: INSERT IN Datenbank1.dbo.Websites (CompanyID, SiteRoot, Active) VALUES (@ p0, @ p1, @ p2); Wählen Sie SCOPE_IDENTITY(); @ p0 = NULL [Typ: Int32 (0)], @ p1 = 'example.com' [Typ: String (4000)], @ p2 = True [Typ: Boolean (0)]

Hier sind die Zuordnungen:

<hibernate-mapping assembly="Models" namespace="Models" xmlns="urn:nhibernate-mapping-2.2" schema="Database1.dbo"> 
    <class name="Website" table="Websites" lazy="true" > 
    <id name="Id" column="ID"> 
     <generator class="identity" /> 
    </id> 
    <many-to-one name="Company" column="CompanyID" fetch="join"/> 
    <property name="SiteRoot"> 
     <column name="SiteRoot" sql-type="nvarchar" length="50" not-null="false" /> 
    </property> 
    <property name="Active"> 
     <column name="Active" sql-type="bit" not-null="true" /> 
    </property> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping assembly="Models" namespace="Models" xmlns="urn:nhibernate-mapping-2.2" schema="Database2.dbo"> 
    <class name="Company" table="Companies" lazy="true" > 
    <id name="Id" column="ID"> 
     <generator class="identity" /> 
    </id> 
    <property name="CompanyId"> 
     <column name="CompanyID" sql-type="int" not-null="true" /> 
    </property> 
    <property name="CompanyName"> 
     <column name="CompanyName" sql-type="nchar" not-null="false" /> 
    </property> 
    <set name="Websites" table="Websites" schema="Database1.dbo" lazy="false"> 
     <key column="CID"/> 
     <one-to-many class="Models.Website, Models" /> 
    </set> 
    </class> 
</hibernate-mapping> 
+0

posten Sie Ihre Mappings ... – DanielVorph

+0

@DanielVorph Frage aktualisiert, um Zuordnungen – Siada

+1

Webseite Klasse CompanyID Eigenschaft mit int-Typ ich denke, so in Ihrem Mapping Sie CompanyID mit Typ-Unternehmen haben, müssen CompanyID Eigenschaft Unternehmensart sein statt von Int-Typ – DanielVorph

Antwort

1

Sie müssen der Eigenschaft Company eine Firma zuweisen, um die Viele-zu-Eins-Beziehung zu implementieren. Etwas wie folgt aus:

var website = new Website 
{ 
    Active = true, 
    SiteRoot = "example.com", 
    Company = session.Load(100); 
}; 

Oder, wenn Sie möchten, verwenden Sie ein Repository:

var website = new Website 
{ 
    Active = true, 
    SiteRoot = "example.com", 
    Company = CompanyRepository.Get(100); 
}; 

Hinweis:

  • session.Load laden nicht alles aus der Datenbank, wenn faul Laden ist aktiviert. Es erstellt nur einen Proxy. Dies ist sehr effizient. Am Ende erstellt es nur eine INSERT-Anweisung für die Website mit einem Fremdschlüssel von 100, ohne den objektorientierten Programmierstil in Ihrem Code zu verlieren.

  • Greifen Sie niemals auf Fremdschlüssel im Klassenmodell zu. Fremdschlüssel werden von NHibernate verwaltet und sind nicht in einem objektorientierten Modell vorhanden.

+0

Ich öffnete die Arbeit, die ich in meine Antwort einfügte, da dies mehr Sinn macht, fügte ich meinem WesiteRepository hinzu: website.Company = session.Load (website.CompanyId) das ist lazily geladen, also fragt nicht wirklich nach der Firma und dann Die ID wird korrekt eingefügt. – Siada

0

es behoben, durch das Mapping many-to-one Einstellung = "false" zu setzen und update = "false" und fügte dann die CompanyID Eigenschaft auf der Website Mapping.