Get id of new record in DNN Module - asp.net

Am new to DNN Module development and using MVC and Linq. Have built a class and controller that allows me to create a record in a table on the database. Can anyone tell me the best way to retrieve the id of the newly created record? The part of the controller for creating the record is below.
class BlockController
{
public void CreateBlock(Block b)
{
using (IDataContext ctx = DataContext.Instance())
{
var rep = ctx.GetRepository<Block>();
rep.Insert(b);
}
}
}
Call to the controller from the code
var bC = new BlockController();
var b = new Block()
{
SectionId = int.Parse(ddlPickSection.SelectedValue),
PlanId = int.Parse(ddlPickPlan.SelectedValue),
BlockName = bId,
BlockDesc = "",
xPos = bX,
yPos = bY,
width = arrBWidths[i],
ModuleId = ModuleId,
CreatedOnDate = DateTime.Now,
CreatedByUserId = UserId,
LastModifiedOnDate = DateTime.Now,
LastModifiedByUserId = UserId,
};
bC.CreateBlock(b);
Thanks

When you submit changes (insert the record in DB) the ID would available in b object:
...
rep.InsertOnSubmit(b);
ctx.SubmitChanges();
int desireID = b.id;

Related

.net Querying a Global Secondary Index in DynamoDB via DynamoDBContext

I have a dynamoDB table with a schema as follows:
var request = new CreateTableRequest
{
TableName = tableName,
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement("CompanyId", KeyType.HASH),
new KeySchemaElement("Timestamp", KeyType.RANGE)
},
AttributeDefinitions = new List<AttributeDefinition>
{
new AttributeDefinition("CompanyId", ScalarAttributeType.S),
new AttributeDefinition("Timestamp", ScalarAttributeType.N),
new AttributeDefinition("UserId", ScalarAttributeType.S)
},
GlobalSecondaryIndexes = new List<GlobalSecondaryIndex>
{
new GlobalSecondaryIndex
{
IndexName = "UserIndex",
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement("UserId", KeyType.HASH),
new KeySchemaElement("Timestamp", KeyType.RANGE)
},
Projection = new Projection {ProjectionType = "ALL"},
ProvisionedThroughput = new ProvisionedThroughput(5, 6)
}
},
ProvisionedThroughput = new ProvisionedThroughput(5, 6)
};
I can query the primary key successfully as follows:
var client = new AmazonDynamoDBClient();
using (var context = new DynamoDBContext(client))
{
var sortKeyValues = new List<object>{minTimestamp};
result = await context.QueryAsync<AuditLogEntry>(companyId, QueryOperator.GreaterThanOrEqual, sortKeyValues,
new DynamoDBOperationConfig {OverrideTableName = TableName}).GetRemainingAsync();
}
And I can query the global secondary index without any constraint on the range key as follows:
var client = new AmazonDynamoDBClient();
using (var context = new DynamoDBContext(client))
{
result = await context.QueryAsync<AuditLogEntry>(userId, new DynamoDBOperationConfig {OverrideTableName = TableName, IndexName = indexName})
.GetRemainingAsync();
}
But when I try to query the index with a range key constraint:
var client = new AmazonDynamoDBClient();
using (var context = new DynamoDBContext(client))
{
var sortKeyValues = new List<object> {minTimestamp};
result = await context.QueryAsync<AuditLogEntry>(userId, QueryOperator.GreaterThan, sortKeyValues, new DynamoDBOperationConfig {OverrideTableName = TableName, IndexName = indexName}).GetRemainingAsync();
}
I get the following error:
Exception thrown: 'System.InvalidOperationException' in AWSSDK.DynamoDBv2.dll
Additional information: Local Secondary Index range key conditions are used but no index could be inferred from model. Specified index name = UserIndex
Googling this error hasn't thrown any light on the issue. The reference to Local Secondary Index has me confused because I'm using a Global index, but I just can't see what's wrong with my code.
I've been able to get the query working by querying directly on the AmazonDynamoDBClient rather than using DynamoDBContext, but I'd really like to understand what I'm doing wrong and be able to use DynamoDBContext.
Any ideas would be appreciated.
In your model definition for AuditLogEntry you need to decorate properties that are part of the global secondary index with attributes - [DynamoDBGlobalSecondaryIndexRangeKey] and or [DynamoDBGlobalSecondaryIndexHashKey]. Example below.
public class AuditLogEntry {
// other properties ...
[DynamoDBProperty("UserId")]
[DynamoDBGlobalSecondaryIndexHashKey("UserIndex")]
public string UserId { get; set; }
}

use isolation level snapshot entity framework 4

I'm try to using a TransactionScope with isolation level snapshot on Entity framework 4 in asp.net web proyect and sql server 2012 standard edition. I'm getting this error Transactions with IsolationLevel Snapshot cannot be promoted.
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot })) {
using (var db = new Datos.TestDBDataContext(System.Configuration
.ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString))
{
Datos.Contacto newUser = new Datos.Contacto
{
name = user.name,
lastName = user.lastName,
type = user.type,
userId = user.userId,
email = user.Email,
password = Password(),
jobCode = user.JobCode,
DateCreated = user.DateCreated,
cityCode = user.cityCode,
numberPass = user.numberPass,
place = user.place,
estate = false
};
db.Contacts.InsertOnSubmit(newUser);
db.SubmitChanges();
}
scope.Complete();
}
What I'm doing wrong ?
Please try as shown below.Set the IsolationLevel.Serializable.
Serializable : Volatile data can be read but not modified, and no new
data can be added during the transaction.
IsolationLevel Enumeration
var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions {
IsolationLevel = IsolationLevel.Snapshot,
IsolationLevel = IsolationLevel.Serializable,
})

Can I generate SQL scripts with ServiceStack OrmLite?

Is it possible to generate SQL scripts using OrmLite without executing it against a database? I would like to load a list of DTOs from a live SqlServer database and output a script to DELETE and INSERT each record.
The provided mini profiler supports logging, but looks like it needs to wrap a real database connection.
This is trivial now that OrmLite extension methods are now mockable by providing your own OrmLiteResultsFilter.
E.g. this ResultsFilter below records every sql statement executed and inherts the behavior from OrmLiteResultsFilter to return empty results:
public class CaptureSqlFilter : OrmLiteResultsFilter
{
public CaptureSqlFilter()
{
SqlCommandFilter = CaptureSqlCommand;
SqlCommandHistory = new List<SqlCommandDetails>();
}
private void CaptureSqlCommand(IDbCommand command)
{
SqlCommandHistory.Add(new SqlCommandDetails(command));
}
public List<SqlCommandDetails> SqlCommandHistory { get; set; }
public List<string> SqlStatements
{
get { return SqlCommandHistory.Map(x => x.Sql); }
}
}
You can wrap this in an using scope to capture each SQL statement without executing them, e.g:
using (var captured = new CaptureSqlFilter())
using (var db = OpenDbConnection())
{
db.CreateTable<Person>();
db.Select<Person>(x => x.Age > 40);
db.Single<Person>(x => x.Age == 42);
db.Count<Person>(x => x.Age < 50);
db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse" });
db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" });
db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < #age",
new { age = 50 });
db.SqlList<Person>("exec sp_name #firstName, #age",
new { firstName = "aName", age = 1 });
db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}"
.SqlFmt("WaterHouse", 7));
var sql = string.Join(";\n\n", captured.SqlStatements.ToArray());
sql.Print();
}
Which prints out:
CREATE TABLE "Person"
(
"Id" INTEGER PRIMARY KEY,
"FirstName" VARCHAR(8000) NULL,
"LastName" VARCHAR(8000) NULL,
"Age" INTEGER NOT NULL
);
;
SELECT "Id", "FirstName", "LastName", "Age"
FROM "Person"
WHERE ("Age" > 40);
SELECT "Id", "FirstName", "LastName", "Age"
FROM "Person"
WHERE ("Age" = 42)
LIMIT 1;
SELECT COUNT(*) FROM "Person" WHERE ("Age" < 50);
INSERT INTO "Person" ("Id","FirstName","LastName","Age") VALUES (#Id,#FirstName,#LastName,#Age);
UPDATE "Person" SET "FirstName"=#FirstName, "LastName"=#LastName, "Age"=#Age WHERE "Id"=#Id;
DELETE FROM "Person" WHERE "FirstName"=#FirstName AND "Age"=#Age;
SELECT LastName FROM Person WHERE Age < #age;
exec sp_name #firstName, #age;
UPDATE Person SET LastName='WaterHouse' WHERE Id=7
More examples available in CaptureSqlFilterTests.cs
As CaptureSqlFilter is useful I've just added it to OrmLite in this commit which will be in the next v4.0.20 that's now available on MyGet.
Using the DialectProvider directly seems to work well enough for what I need. ToInsertRowStatement takes a IDbCommand paramater, but does not use it so null works.
OrmLiteConfig.DialectProvider = SqlServerOrmLiteDialectProvider.Instance;
var dto = new PersonDTO { Id = Guid.NewGuid(), Name = "Carl" };
var deleteText = SqlServerOrmLiteDialectProvider.Instance.ToDeleteRowStatement(dto);
var insertText = SqlServerOrmLiteDialectProvider.Instance.ToInsertRowStatement((IDbCommand)null, dto);
Is there a better alternative?
I use this to capture the statement and keep running the sentense.
public class CustomOrmLiteExecFilter : OrmLiteExecFilter
{
public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter)
{
var holdProvider = OrmLiteConfig.DialectProvider;
var dbCmd = CreateCommand(dbConn);
try
{
var ret = filter(dbCmd);
var pureSQL = holdProvider.MergeParamsIntoSql(dbCmd.CommandText, dbCmd.Parameters.OfType<IDbDataParameter>());
//log or save the SQL Statement
return ret;
}
finally
{
if (OrmLiteConfig.DialectProvider != holdProvider)
OrmLiteConfig.DialectProvider = holdProvider;
}
}
}
and the usage:
OrmLiteConfig.ExecFilter = new CustomOrmLiteExecFilter();
hope this can help you!

Querystring display details

I got this tblDocument table which has a one to many relationship to a couple of other tables. I have created this querystring that displays the content of the document. In this soulution i only display the DocPerson id. What im trying to do is to display the name of the person which is located in the tblPerson table. Can someone help me?
if (!IsPostBack)
{
string strId = Request.QueryString["id"];
int id;
if (int.TryParse(strId, out id))
{
var db = new MyModelContext();
var p = db.tblDocuments.SingleOrDefault(x => x.DocId == id);
if (p != null)
{
lblCaseNr.Text = p.DocNr;
lblPerson.Text = p.DocPerson.ToString();
lblCourt.Text = p.DocCourt.ToString();
lblYear.Text = p.Docyear.ToString();
lblResume.Text = p.DocResume;
lblResult.Text = p.DocResult;
lblLaw.Text = p.DocLaw.ToString();
}
}
}
}
For your LINQ expression, try the following:
var q = from d in db.tblDocuments join p in db.tblPerson
on d.DocId equals p.DocId
where d.DocId == id
select new {d.DocId, p.DocPerson}
If you need to access other fields, simply add them to your select new clause.

LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression

LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
public ActionResult PopulateFromDB(string sidx, string sord, int page, int rows)
{
var context = new NerdDinnerEntities();
var jsonData = new
{
total = 1,
page = page,
sord =sord,
records = context.Authors.Count(),
rows = (from n in context.Authors
select new
{ AuthorId = n.AuthorId ,
cell = new string[] { n.AuthorId.ToString(), n.Name.ToString(), n.Location.ToString() }
}).ToList()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
I am writting ToList or Toarray is it not working the error comes :
public ActionResult PopulateFromDB(string sidx, string sord, int page, int rows)
{
var context = new NerdDinnerEntities();
var jsonData = new
{
total = 1,
page = page,
sord =sord,
records = context.Authors.Count(),
rows = (from n in context.Authors
select new
{ AuthorId = n.AuthorId ,
cell = new string[] { n.AuthorId.ToString(), n.Name.ToString(), n.Location.ToString() }
}).ToList()
};
return Json(jsonData,JsonRequestBehavior.AllowGet);
}
From your code I assume your adding a custom property cell for display/storage purposes on the client-side. I would avoid this as your essentially coupling your API call to one particular client. I would suggest you simply return the data required & deal with it at the client-side specifically e.g.
Server
...
select new
{
Id = n.AuthorId,
Name = n.Name,
Location = n.Location
}).ToList();
...
Client
var response = ...
foreach (var author in response)
{
var cell = new string[] { author.Id.ToString(), author.Name, author.Location };
// do something with cell
}
You should try SqlFunctions.StringConvert to convert this, There is no overload for int so you should cast your number to a double or a decimal.
public ActionResult PopulateFromDB(string sidx, string sord, int page, int rows)
{
var context = new NerdDinnerEntities();
var jsonData = new
{
total = 1,
page = page,
sord =sord,
records = context.Authors.Count(),
rows = (from n in context.Authors
select new
{ AuthorId = n.AuthorId ,
cell = new string[] { SqlFunctions.StringConvert((double)n.AuthorId), n.Name, n.Location }
}).ToList()
};
return Json(jsonData,JsonRequestBehavior.AllowGet);
}
You are not using LinqToSql Classes, if you were using that your code should work, but as you mention that you are using LinqToEntity then You should use SqlFunctions.StringConvert to convert to string.

Resources