Table of Contents [Hide/Show]
Data Providers Initializing A Data Provider Gemli.Data.Providers.DbDataProvider Gemli.Data.Providers.MemoryDataProvider One-Time Referencing Of The Initialized ProviderDataModel and DataModel<T> Gemli.Data.DataModel (inheriting) Gemli.Data.DataModel<TEntity> (wrapping)Saving Data DataModel.Save() DataProvider.SaveModel() Loading Data Queries Query Conditions Requesting Data Single Record Multiple RecordsTransactions Creating A Transaction Rolling BackLoading and Saving With Stored ProceduresRelationships (Deep Loads and Deep Saves) Executing Deep Loads and Deep Saves DataProviderBase.DeepLoadModel() n -Level Depth Recursion Upon Same Records DataProviderBase.DeepLoadModels() DataProviderBase.DeepSaveModel() DataProviderBase.DeepSaveModels() DataModel.Save(deep, ...) Declaring Relationships ForeignDataModelAttribute ForeignKeyAttribute Many-To-Many ScenariosLoading Mappings From XMLCustomizing Mappings At Runtime Table Mapping Column Mappings Foreign Mappings Iterating And Modifying The DataModelMap Items
myQuery.WhereProperty["ID"].IsEqualTo(2)
myQuery.WhereColumn["mytable_id"].IsEqualTo(2)
var dr = new DataModel<MyPoco>(myObject).Convert.ToDataRow();
// attributes only used where the schema is not inferred // inferred: [DataModelTable(Schema = "dbo", Table = "SamplePoco")] public class SamplePoco { // inferred: [DataModelColumn("ID", IsPrimaryKey = true, IsIdentity = true, // IsNullable = false, DataType = DbType.Int32)] // note: DbType.Int32 is SQL type: int public int ID { get; set; } // inferred: [DataModelColumn("SampleStringValue", IsNullable = true, // DataType = DbType.String)] // note: DbType.String is SQL type: nvarchar public string SampleStringValue { get; set; } // inferred: [DataModelColumn("SampleDecimalValue", IsNullable = true, // DataType = DbType.Decimal)] // note: DbType.Decimal is SQL type: money public decimal? SampleDecimalValue { get; set; } }[TestMethod] public void CreateAndDeleteEntityTest() { var sqlFactory = System.Data.SqlClient.SqlClientFactory.Instance; var dbProvider = new DbDataProvider(sqlFactory, TestSqlConnectionString); // create my poco var poco = new SamplePoco { SampleStringValue = "abc" }; // wrap and auto-inspect my poco var dew = new DataModel<SamplePoco>(poco); // data entity wrapper // save my poco dew.DataProvider = dbProvider; dew.Save(); // auto-synchronizes ID // or... //dbProvider.SaveModel(dew); //dew.SynchronizeFields(SyncTo.ClrMembers); // manually sync ID // now let's load it and validate that it was saved var mySampleQuery = DataModel<SamplePoco>.NewQuery() .WhereProperty["ID"] == poco.ID; // poco.ID was inferred as IsIdentity so we auto-returned it on Save() var data = dbProvider.LoadModel(mySampleQuery); Assert.IsNotNull(data); // success! // by the way, you can go back to the POCO type, too SamplePoco poco2 = data.Entity; // no typecast nor "as" statement Assert.IsNotNull(poco2); Assert.IsTrue(poco2.ID > 0); Assert.IsTrue(poco2.SampleStringValue == "abc"); // test passed, let's delete the test record data.MarkDeleted = true; data.Save(); // ... and make sure that it has been deleted data = dbProvider.LoadModel(mySampleQuery); Assert.IsNull(data);}
var mySampleQuery = DataModel<SamplePoco>.NewQuery() .WhereColumn["SampleStringValue"].IsLike("%bc"); var models = dbProvider.LoadModels(mySampleQuery); SamplePoco theFirstSamplePocoEntity = models.Unwrap<SamplePoco>()[0]; // or.. SamplePoco theFirstSamplePocoEntity = models[0].Entity;
Gemli.Data.Providers.DataProviderBase
Gemli.Data.Provider.DbDataProvider
System.Data.DbFactory
DbDataProvider
var sqlFactory = System.Data.SqlClient.SqlClientFactory.Instance; var dbProvider = new Gemli.Data.Providers.DbDataProvider(sqlFactory, AppSqlConnectionString);
Gemli.Data.Providers.MemoryDataProvider
DataTable
var memProvider = new MemoryDataProvider();// add a table var dt = new System.Data.DataTable("Company"); var companyIdCol = new DataColumn("company_id", typeof (int)); dt.Columns.Add(companyIdCol); var companyNameCol = new DataColumn("company_name", typeof (string)); dt.Columns.Add(companyNameCol); memProvider.AddTable(dt);
var sqlFactory = System.Data.SqlClient.SqlClientFactory.Instance; var dbProvider = new Gemli.Data.Providers.DbDataProvider(sqlFactory, AppSqlConnectionString);// Assign as application default provider Gemli.Data.Providers.ProviderDefaults.AppProvider = dbProvider;
Gemli.Data.DataModel<T>
Gemli.Data.DataModel
DataModel
// A basic DataModel class. public class Customer : DataModel { [DataModelColumn("customer_id")] public virtual int ID { get { return (int)base["ID"]; } set { base["ID"] = value; } } [DataModelColumn("customer_name")] public virtual string Name { get { return (string) base["Name"]; } set { base["Name"] = value; } } }
Gemli.Data.DataModel<TEntity>
DataModel<TEntity>
Gemli.Data.DataModelMap
System.Reflection
TEntity
PropertyLoadBehavior
[DataModelTable]
InferProperties.NotIgnored
[DataModelIgnore]
ForeignDataModel
public class Customer // : object, or your own base class { [DataModelColumn("customer_id")] public virtual int ID { get; set; } [DataModelColumn("customer_name")] public virtual string Name { get; set ] }...var customer = new Customer {Name = "Jon"}; DataModel customerDataModel = new DataModel<Customer>(customer);
.Save()
.DataProvider
.SaveModel(dataModel)
Gemli.Data.DataModelCollection
DataModel.Save()
Save(..)
LoadDataModel(..)
DataProvider
var sqlFactory = System.Data.SqlClient.SqlClientFactory.Instance; var dbProvider = new Gemli.Data.Providers.DbDataProvider(sqlFactory, AppSqlConnectionString); Gemli.Data.Providers.ProviderDefaults.AppProvider = dbProvider;var contact = new Contact(); contact.Name = "Bob Smith"; var contactModel = new DataModel<Contact>(myContactObject); contactModel.Save();
var contact = new Contact(); contact.Name = "Bob Smith";var contactModel = new DataModel<Contact>(myContactObject);var sqlFactory = System.Data.SqlClient.SqlClientFactory.Instance; var dbProvider = new Gemli.Data.Providers.DbDataProvider(sqlFactory, AppSqlConnectionString); contactModel.DataProvider = dbProvider;contactModel.Save();
var sqlFactory = System.Data.SqlClient.SqlClientFactory.Instance; var dbProvider = new Gemli.Data.Providers.DbDataProvider(sqlFactory, AppSqlConnectionString);var contactQuery = DataModel<Contact>.NewQuery() .WhereProperty["Name"] == "Bob Smith"; var contactModel = dbProvider.LoadModel(contactQuery);contactModel.Entity.Salary += 10000m; // give Bob a raisecontactModel.Save(); // contactModel already knows its DataProvider
DataProvider.SaveModel()
SaveModel(..)
dataModel.SynchronizeFields(SyncTo.FieldMappedData);
dataModel.SynchronizeFields(SyncTo.ClrMembers);
dataModel.SynchronizeFields(SyncTo.FieldMappedData); dataProvider.SaveModel(dataModel); dataModel.SynchronizeFields(SyncTo.ClrMembers);
DataModel<T>
Gemli.Data.DataModelCollection<T>
Gemli.Data.Query<T>
Query<T>
.NewQuery()
var customerQuery = DataModel<Customer>.NewQuery();
var customerQuery = DataModel<Customer>.NewQuery() .WhereProperty["salary"].IsGreaterThan(60000m) .WhereProperty["department"].IsEqualTo("Sales");
.IsEqualTo(value)
== value
DataModels
DataModelQuery<TModel>
DataModelQuery<T>
.Load()
LoadModel()
DataRow
IDataReader
var sqlFactory = SqlClientFactory.Instance; var dbProvider = new DbDataProvider(sqlFactory, TestSqlConnection);var myCustomerQuery = DataModel<Customer>.NewQuery() .WhereColumn["customer_id"].IsEqualTo(153); DataModel<Customer> customer = myCustomerQuery.SelectFirst();
var sqlFactory = SqlClientFactory.Instance; var dbProvider = new DbDataProvider(sqlFactory, TestSqlConnection);var myCustomerQuery = DataModel<Customer>.NewQuery() .WhereColumn["customer_id"].IsEqualTo(153); DataModel<Customer> customer = DataModel<Customer>.Load(myCustomerQuery);
var sqlFactory = SqlClientFactory.Instance; var dbProvider = new DbDataProvider(sqlFactory, TestSqlConnection);var myCustomerQuery = DataModel<Customer>.NewQuery() .WhereColumn["customer_id"].IsEqualTo(153); DataModel<Customer> customer = dbProvider.LoadModel(myCustomerQuery);
DataModelCollection<T>
LoadModels()
var customersQuery = DataModel<Customer>.NewQuery() .WhereProperty["IsActive"].IsEqualTo(true); var customers = customersQuery.SelectMany();
var customersQuery = DataModel<Customer>.NewQuery() .WhereProperty["IsActive"].IsEqualTo(true); var customers = DataModel<Customer>.LoadMany(customersQuery);
var customersQuery = DataModel<Customer>.NewQuery() .WhereProperty["IsActive"].IsEqualTo(true); var customers = dbProvider.LoadModels(customersQuery);
Save()
SyncronizeFields()
Load()
DataProviderBase
System.Data.DbTransaction
DbCommand
DbFactory
SupportsTransactions
BeginTransaction
BeginTransaction(IsolationLevel)
Reset(ResetMode)
OriginalData
ModifiedProperties
IsNew
MarkDeleted
ColumnName
[DataModelColumn]
Gemli.Data.DataProviderBase
DeepLoadModel(...)
LoadModel(...)
depth
null
TModel
DeepLoad
DeepLoadModels(...)
DataModelCollection<TModel>
DeepSaveModel(...)
DeepSaveModels(...)
ForeignDataModelAttribute
ForeignKeyAttribute
[DataModel("customer")] public class Customer { [DataModelColumn("customer_id")] public int ID { get; set; } [ForeignDataModel( ColumnName = "billing_address_id", ForeignColumnName = "address_id", Relationship = Relationship.OneToOne] public Address MailingAddress { get; set; }}
ForeignColumnName
[ForeignKey]
AssignToMember
[DataModel("customer")] public class Customer { [DataModelColumn("customer_id")] public int ID { get; set; } public Address MailingAddress { get; set; } [ForeignKey( Relationship = Relationship.OneToOne, RelatesTo = typeof(Address), ForeignColumn = "address_id", AssignToMember = "MailingAddress" )] public int MailingAdressID { get; set; } }
-- A simple User table, doesn't know Groups CREATE TABLE [dbo].[User]( [user_id] [uniqueidentifier] NOT NULL, [user_name] [varchar](250) NULL, CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ( [user_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO-- A simple Group table, doesn't know Users CREATE TABLE [dbo].[Group]( [group_id] [uniqueidentifier] NOT NULL, [group_name] [varchar](250) NULL, CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED ( [group_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO-- A Group-User mapping table, allows a user to have many groups, -- allows a group to have many users. CREATE TABLE [dbo].[GroupUser]( [groupuser_id] [bigint] IDENTITY(1,1) NOT NULL, [user_id] [uniqueidentifier] NOT NULL, [group_id] [uniqueidentifier] NOT NULL, CONSTRAINT [PK_GroupUser] PRIMARY KEY CLUSTERED ( [groupuser_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]GOALTER TABLE [dbo].[GroupUser] WITH CHECK ADD CONSTRAINT [FK_GroupUser_Group] FOREIGN KEY([group_id]) REFERENCES [dbo].[Group] ([group_id]) GOALTER TABLE [dbo].[GroupUser] CHECK CONSTRAINT [FK_GroupUser_Group] GOALTER TABLE [dbo].[GroupUser] WITH CHECK ADD CONSTRAINT [FK_GroupUser_User] FOREIGN KEY([user_id]) REFERENCES [dbo].[User] ([user_id]) GOALTER TABLE [dbo].[GroupUser] CHECK CONSTRAINT [FK_GroupUser_User] GO
public class Group { [DataModelColumn("group_id", IsPrimaryKey = true)] public Guid ID { get; set; } [DataModelColumn("group_name")] public string Name { get; set; } [ForeignDataModel(Relationship = Relationship.ManyToMany, MappingTable = "GroupUser")] public List<User> Users { get; set; } }public class User { [DataModelColumn("user_id", IsPrimaryKey = true)] public Guid ID { get; set; } [DataModelColumn("user_name")] public string Name { get; set; } [ForeignDataModel(Relationship = Relationship.ManyToMany, MappingTable = "GroupUser")] public List<Group> Groups { get; set; } }
MappingTable
DataModelMap.LoadMappings(..)
<?xml version="1.0"?> <mappings> <mappingItem> <class>Tests.Gemli.Data.MemoryDataProviderTest+MockPoco, Tests.Gemli.Data</class> <dataModel> <entityType>Tests.Gemli.Data.MemoryDataProviderTest+MockPoco</entityType> <tableMapping> <table>mock_table</table> <schema>dbo</schema> </tableMapping> <columnMappings> <column> <!-- The ownerType element should be the same as the class element above; unfortunately this is not optional in the current build. --> <ownerType>Tests.Gemli.Data.MemoryDataProviderTest+MockPoco</ownerType> <memberName>ID</memberName> <columnName>customentity_id</columnName> <sqlType>Int</sqlType> <isNullable>false</isNullable> <isPrimaryKey>true</isPrimaryKey> <isIdentity>true</isIdentity> <defaultValue>0</defaultValue> </column> <column> <ownerType>Tests.Gemli.Data.MemoryDataProviderTest+MockPoco</ownerType> <memberName>SomeValue</memberName> <columnName>some_value</columnName> <sqlType>NVarChar</sqlType> <isNullable>true</isNullable> <isPrimaryKey>false</isPrimaryKey> <isIdentity>false</isIdentity> </column> </columnMappings> </dataModel> </mappingItem> </mappings>
DataModelMap
DataModelMap.GetEntityMapping(typeof(YOUR_TYPE))
YOUR_TYPE
DataModelMap mapping = DataModelMap.GetEntityMapping(typeof(YOUR_TYPE));
TableMapping
DataModelTableAttribute
ColumnMappings
DataModelColumnAttribute
ForeignModelMappings
DataModelMap.MapItems
Type
var oldMapping = DataModelMap.GetEntityMapping(typeof(MyClass)); var newMapping = new DataModelMap(typeof(MyClass)); newMapping.TableMapping.Table = "MyOtherTable"; DataModelMap.MapItems[typeof(MyClass)] = newMapping;