It's my first LINQ TO SQL Project , So definitely my question could be naive .
Till now I used to create new property in Business Object beside of every DateTime Property , That's because i need to do some processing in my DateTime property and show it in special string format for binding to UI Controls .Like :
private DateTime _insertDate;
///
/// I have "InertDate" field in my Table on Database
///
public DateTime InsertDate
{
get { return _insertDate; }
set { _insertDate = value; }
}
// Because i need to do some processing I create a readonly string property that pass InsertDate to Utility method and return special string Date
public string PInsertDate
{
get { return Utility.ToSpecialDate(_insertDate); }
}
My question is I don't know how to do it in LINQ . I did like follow but i get run time error. "Method 'System.String ToSpecialDate(System.Object)' has no supported translation to SQL"
ToosDataContext db = new ToosDataContext();
var newslist = from p in db.News
select new {p.NewsId,p.Title,tarikh =MD.Utility.ToSpecialDate( p.ReleaseDate)};
GridView1.DataSource = newslist;
GridView1.DataBind();
You need to separate out the query performed in the database from the processing to be done in process. Try this:
var newslist = db.News
// First do a select in SQL
.Select(p => new {p.NewsId, p.Title, p.ReleaseDate})
.AsEnumerable() // Do the rest in process
.Select(p => new {p.NewsId, p.Title,
tarikh = MD.Utility.ToSpecialDate(p.ReleaseDate) });
Related
I'm trying to do in Linq EF this my sql query:
SELECT date FROM tab_4009_atv
WHERE id_asset IN ['ako','bj89','flity76']
GROUP BY date;
but there's a specific situation.
This list that I'm filtering is received as a parameter like this:
public async Task<IEnumerable< Date>> getDates (IEnumerable< string>assetList){ }.
How can I do this? Thanks!
The SQL query and the C# method signature you have given don't really fit each other. SQL query returns a grouping of dates, but the C# method returns a list of dates. We need to modify the return type of the method.
On the other hand, this question is more about converting the string to the Asset object than SQL or LINQ. Since we do not know what the Asset object looks like we cannot help you with that conversion. We have to delegate that responsibility to another method.
Additionally, the method doesn't need to be async.
The following code should do what you are looking for.
public class Asset
{
public DateTime Date { get; set; }
public string? OtherData { get; set; }
}
private static Asset StringToDate(string assetString)
{
// Convert string to asset object
}
public IEnumerable<IGrouping<DateTime, Asset>> GetDates(IEnumerable<string> assetList)
{
var filter = new[] {"ako", "bj89", "flity76"};
var dates = assetList
.Where(x => filter.Contains(x))
.Select(x => StringToDate(x))
.GroupBy(assets => assets.Date);
return dates;
}
I have a PHP class that represent MySQL table. One of that column table type is DateTime. Previously I use string and everything work fine, because I don't have to deal with the date type. I just use fetchAll function and the column table automatically mapping to a propriate field.
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_CLASS, MyPHPClass::class);
Now I want to use the DateTime type in my PHP script. Is this possible to automatically convert MySQL DateTime to PHP DateTime when use PDO fetchAll? If yes, how?
Note:
I know how to convert the DateTime string from MySQL to PHP DateTime, I just wonder if this is possible to add something like #Annotation, or converter.
For this purpose the concept of so called hydrators is very common. Especially for data fields of the type DateTime, which will most likely be repeated in other models, it makes sense to use hydrators. This keeps the logic away from the models and works with reusable code.
Why Hydrators?
If you are considering using your entire development with another database system, or if you simply want to maintain the greatest possible flexibility with your data models, hydrators make perfect sense. As mentioned earlier, hydrators can ensure that the models remain free of any logic. In addition, hydrators can be used to represent flexible scenarios. In addition, the hydration of data solely on the basis of the possibilities offered by the PHP PDO class is very weak. Just handle the raw data from the database as array and let the hydrator do the magic.
The Logic Behind Hydrators
Each hydrator can apply different strategies to the properties of the object to be hydrated. These hydrator strategies can be used to change values or perform other functions in the model before the actual hydration.
<?php
declare(strict_types=1);
namespace Marcel\Hydrator;
interface HydratorInterface
{
public function hydrate(array $data, object $model): object;
public function extract(object $model): array;
}
The above shown interface should be implemented in every hydrator class. Every hydrator should have a hydrate method, which pushes a given array of data into a given model. Furthermore there has to be the turnaround which is the extract method, which extracts data out of an model into an array.
<?php
declare(strict_types=1);
namespace Marcel\Hydrator\Strategy;
interface StrategyInterface
{
public function hydrate($value);
}
Both interfaces define the methods that hydrators and hydrator strategies must bring. These interfaces are mainly used to achieve secure type hinting for the identification of objects.
The Hydrator Strategy
<?php
declare(strict_types=1);
namespace Marcel\Hydrator\Strategy;
use DateTime;
class DateTimeStrategy implements StrategyInterface
{
public function hydrate($value)
{
$value = new DateTime($value);
return $value;
}
}
This simple example of an hydrator strategy does nothing more than taking the original value and initializing a new DateTime object with it. For the sake of simple illustration, I have omitted the error handling here. In production, you should always check at this point whether the DateTime object was really created and did not generate any errors.
The Hydrator
<?php
declare(strict_types=1);
namespace Marcel\Hydrator;
use Marcel\Hydrator\Strategy\StrategyInterface;
use ReflectionClass;
class ClassMethodsHydrator implements HydratorInterface
{
protected ?ReflectionClass $reflector = null;
protected array $strategies = [];
public function hydrate(array $data, object $model): object
{
if ($this->reflector === null) {
$this->reflector = new ReflectionClass($model);
}
foreach ($data as $key => $value) {
if ($this->hasStrategy($key)) {
$strategy = $this->strategies[$key];
$value = $strategy->hydrate($value);
}
$methodName = 'set' . ucfirst($key);
if ($this->reflector->hasMethod($methodName)) {
$model->{$methodName}($value);
}
}
return $model;
}
public function extract(object $model): array
{
return get_object_vars($model);
}
public function addStrategy(string $name, StrategyInterface $strategy): void
{
$this->strategies[$name] = $strategy;
}
public function hasStrategy(string $name): bool
{
return array_key_exists($name, $this->strategies);
}
}
This hydrator requires that your models have getter and setter methods. In this example, it requires at least that there is a corresponding setter method for each property. To avoid errors and to name methods correctly, the names of the column names should be filtered from the database. Normally, the names in the database are noted with an underscore and the properties of a model follow the camel case convention. (Example: "fancy_string" => "setFancyString")
The Example
class User
{
protected int $id;
protected DateTime $birthday;
public function getId(): int
{
return $this->id;
}
public function setId(int $id): void
{
$this->id = $id;
}
public function getBirtday(): DateTime
{
return $this->birthday;
}
public function setBirthday(DateTime $birthday): void
{
$this->birthday = $birthday;
}
}
$data = [
'id' => 1,
'birthday' => '1979-12-19',
];
$hydrator = new ClassMethodsHydrator();
$hydrator->addStrategy('birthday', new DateTimeStrategy());
$user = $hydrator->hydrate($data, new User());
The result of this code will be a fine hydrated user model.
object(Marcel\Model\User)#3 (2) {
["id":protected] => int(1)
["birthday":protected] => object(DateTime)#5 (3) {
["date"] => string(26) "1979-12-19 00:00:00.000000"
["timezone_type"] => int(3)
["timezone"] => string(13) "Europe/Berlin"
}
We can take advantage of the fact that PHP will call __set magic method for all undefined properties so we can initialize our DateTime object there.
class User {
public string $name;
public DateTime $dateObject;
public function __set($property, $value) {
if ($property === 'date') {
$this->dateObject = new DateTime($value);
} else {
$this->$property = $value;
}
}
}
$stmt->fetchAll(PDO::FETCH_CLASS, User::class);
Note: the column name in the database must differ from the property name in the User object, otherwise __set method will not be called.
MySQL save datetime as unix timestamp and return all dates as timestamps if we get it as string , then we are convert in timestamp
Example: - date('m/d/Y H:i:s', 1541843467);
My XML:
<destinations>
<destination>
<fav>1</fav>
<cheapest>140</cheapest>
</destination>
<destination>
<fav>0</fav>
<cheapest>150</cheapest>
</destination>
</destinations>
I am creating XMLListCollection for my spark List component.
var dataprovider:XMLListCollection = new XMLListCollection(xml.destination);
I am trying to sort this XMLListCollection using fav and cheapest element.
var sort:Sort = new Sort();
sort.fields = [new SortField("fav" , true , true)];
sort.fields.push(new SortField("cheapest" , false , true));
dataprovider.sort = sort;
dataprovider.refresh();
Everything works fine till I update value of fav:
xml.destination.(id == String(destId))[0].fav = 0;
XML structure looks exactly the same after the update but I get thrown error from my itemrenderer object :
override public function set data( value:Object ) : void {
dest_name.text = value.text;
}
Error stating that value is null. How can value be null in the first place? I get no error when I remove fav from sort fields or update cheapest element instead.
Does anyone have any idea about this anomaly?
You have to take into account that your itemrenderers are recycled, for example, if order of items in your collection changes(when you change value of sort field). When renderers are recycled, null can be passed to set data function.
That means your function
override public function set data( value:Object ) : void {
dest_name.text = value.text;
}
shall be changed like that:
override public function set data( value:Object ) : void {
if(value){
dest_name.text = value.text;
}
}
You should always keep this in mind when implementing item renderers.
I am using Liferay and developing my custom portlet, now I want to use custom query to retrieve some data from multiple table with joins etc.
I have googled the things for my problem but can't find the simple way to understand the step-by-step procedure.
So if any one can guide me or give me any tutorial to create Custom SQL query for my custom portlet.
after this 4th step i have built my service in eclipse,and its showing successfully.there are two file created in service/persistence package with the name AdvertiseFinder.java and AdvertiseFinderUtil.java but when i try to access the method getAd_DisplayforReports with the advertiseFinderUtil.getAd_DisplayforReports("Any arguement with string")
its giving me error that no such method in AdvertiseFinderUtil
I have build the service after updating my AdvertiseFinderImpl Method.but its not working
this is my AdvertiseFinderImpl Class
package emenu.advertise.database.service.persistence;
import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;
import emenu.advertise.database.model.ad_display;
import emenu.advertise.database.model.advertise;
import emenu.advertise.database.model.impl.ad_displayImpl;
import java.util.List;
import com.liferay.portal.SystemException;
import com.liferay.portal.kernel.dao.orm.QueryPos;
import com.liferay.portal.kernel.dao.orm.SQLQuery;
import com.liferay.portal.kernel.dao.orm.Session;
import com.liferay.util.dao.orm.CustomSQLUtil;
public class AdvertiseFinderImpl extends BasePersistenceImpl<ad_display> implements advertiseFinder{
public void getall() {
}
// the name of the query
public static String GET_ADVERTISE = AdvertiseFinderImpl.class.getName()
+ ".getAdvertise";
// the method which will be called from the ServiceImpl class
public List<ad_display> getAd_DisplayforReports(String pattern) throws SystemException {
Session session = null;
try {
// open a new hibernate session
session = openSession();
// pull out our query from book.xml, created earlier
String sql = CustomSQLUtil.get(GET_ADVERTISE);
// create a SQLQuery object
SQLQuery q = session.createSQLQuery(sql);
// replace the "Book" in the query string with the fully qualified java class
// this has to be the hibernate table name
q.addEntity("a_ad_display", ad_displayImpl.class);
// Get query position instance
QueryPos qPos = QueryPos.getInstance(q);
// fill in the "?" value of the custom query
// this is same like forming a prepared statement
qPos.add(pattern);
// execute the query and return a list from the db
return (List<ad_display>)q.list();
/*
// use this block if you want to return the no. of rows (count)
int rows = 0;
Iterator<Long> itr = q.list().iterator();
if (itr.hasNext()) { Long count = itr.next();
if (count != null) { rows = count.intValue(); } }
return rows;
*/
} catch (Exception e) {
throw new SystemException(e);
} finally {
closeSession(session);
}
}
}
my default-ext.xml is following
<?xml version="1.0"?>
<custom-sql>
<sql file="custom-sql/emenu.xml" />
</custom-sql>
my emenu.xml is here
<custom-sql>
<sql id="emenu.advertise.database.service.persistence.AdvertiseFinderImpl.getAd_DisplayforReports">
<![CDATA[
SELECT
*
FROM
a_ad_display
]]>
</sql>
</custom-sql>
change
return (List<ad_display>)q.list();
to
return (List<ad_display>) QueryUtil.list(q, getDialect(), -1, -1);
Following are the steps to write custom query / finder methods in Liferay:
Create a new finder called EntityFinderImpl.java in the /generated/service/persistence directory.
'build-service' on the project.
The ServiceBuilder autogenerates the following two extra files: EntityFinder.java and EntityFinderUtil.java
Now open the EntityFinderImpl.java file and let this class extend the BasePersistenceImpl and implement EntityFinder. (Assumed that the Entity (table-name) is defined in the service.xml and other required classes are also autogenerated by ServiceBuilder)
Now add required custom method to EntityFinderImpl.java and build service again to distribute this method to Util classes.
Custom method can be created using liferay's DynamicQuery API or SQL-query as following:
public List<Entity> getCustomDataFromFinder("Parameters") throws SystemException {
Session session = null;
StringBuilder queryString = new StringBuilder();
Entity e = new EntityImpl();
try {
session = openSession();
queryString.append(" Write your Query here and conditionally append parameter value(s).");
SQLQuery query = session.createSQLQuery(queryString.toString());
query.addEntity("EntityName", EntityImpl.class);
return (List<Entity>) QueryUtil.list(query, getDialect(), 0, -1);
}
catch (Exception e) {
throw new SystemException(e);
}
finally {
if (session != null) {
closeSession(session);
}
}
}
I am developing a web application with C# & SQL Server 2008.
I have a data reader which reads the column PlayTime, defined as TIME datatype.
I want to write a function that returns PlayTime's value.
private static Timespan GetTime(IDataReader rdr, string columnName)`
{
int index = rdr.GetOrdinal(columnName);
if (rdr.IsDBNull(index))
{
return ; // Here I want to return null or zero
}
return (TimeSpan)rdr[index];
}
Am I right using Timespan for time data type?
How to return null if datareader value is nothing?
Best Regards,
RedsDevils
Something like this:
private static TimeSpan? GetTime(IDataReader rdr, string columnName)
{
int index = rdr.GetOrdinal(columnName);
if (rdr.IsDBNull(index))
{
return null;
}
return (TimeSpan)rdr[index];
}
You need to use nullable Timespan
private static Nullable<TimeSpan> GetTime(IDataReader rdr, string columnName)
{
int index = rdr.GetOrdinal(columnName);
if (rdr.IsDBNull(index))
{
return null;
}
return (Nullable<TimeSpan>)rdr[index];
}